Potential traps when starting long threads on Application_Start

I hope to formulate this post in a legitimate StackOverflow question, as I would really like a solid understanding of this scenario, but I could definitely see if it is too localized or considered an “opinion”.

Here is my scenario: when I load my web application, I load a whole bunch of data from the database and cache it. The problem is that this process takes about 10-15 seconds and creates a delay on the first start of the web server. This is annoying during development, and also causes some problems when I give up the web server in production (since this is a new site, I often hotly fix small errors when I find them, or reset IIS settings).

I had to wonder - can I offload this work to a new thread when the application starts, and this happens in the background, as other users use this site? Obviously, some functions will not work for 10-15 seconds when loading the site, but I can process this condition or block until the data becomes available. At first I thought not. The web server was about to either terminate these threads if the request ended, or was blocked until these threads ended. I decided to write a small test application to test this theory:

public class Global : System.Web.HttpApplication { void Application_Start(object sender, EventArgs e) { Thread thread = new Thread(LoadData); thread.Start(); } private void LoadData() { for (int i = 0; i < 100; i++) { Trace.WriteLine("Counter: " + i.ToString()); Thread.Sleep(1000); } } } 

When the application starts, I started a new thread, and its number will be equal to 100. To my great surprise, I immediately got to the home page and in the Visual Studio debug output window, I could see the counter of additional numbers up. I was really surprised that this works.

My questions:

Firstly, are there any problems with this? Is he asking for trouble and will something explode? Will this change change between web servers or versions of IIS, because maybe they use different stream models? I am looking for general information about this design.

+4
source share
2 answers

tl; dr: What you are doing is probably fine, and a general way to handle this situation.

There are, of course, gotchas with threads. Not to say that you should not use them in this case, but you are wise to make sure that you understand them. To abuse the old meme: "Programmers often see the concurrency problem and solve it using a different thread. Now they have two problems."

If your stream is intended for a background stream (this means that it should not prevent your site from shutting down if the stream is still running), make sure that the IsBackground property is set. Better yet, use BackgroundWorker .

How useful is your site before the end of the initialization stream? Is there any real reason for displaying an interface when it is initialized?

I went into my own circles, using flows for concurrency - from being afraid of them, to think that I understood them and hugged them, thinking that I understand them and fear them. Right now, when I have a problem with concurrency / async that I want to solve, I usually try to create an architecture consisting of several interconnected, parallel (but single-threaded) processes. A lot of things are getting easier, and I have had great success with it.

In your current case, using a background thread to handle database loading is probably safe enough if you can assure that you don't have access to the resources that the thread prepares before they are ready. However (if you can target .Net 4.0), the best way to do what you want is to use Task Async , which is to say that your routines are asynchronous and return task T instead of T. Done correctly. this can allow your site to respond to the user, even in a single-threaded environment, and even though it is still loading resources in the background.

+2
source

Get it when you go to use something from the cache that is not there.

I agree with Drew as with BackGroundWorker.

There should be two modes on the site: functions are disabled, which depend on the cache.
When BackGroundWorker is complete, enable all features.
Users do not like how to press a button to say that they are not ready to try again later.

+1
source

Source: https://habr.com/ru/post/1440148/


All Articles