views:

194

answers:

3

Hi Everyone,

I was working on a project and there is bulk e-mail sending part of it and when user clicks on the button, he/she gets the "Thanks the e-mails have been sent" immediately as a Response and the same method is firing an async thread as well.

ThreadPool.QueueUserWorkItem(SendEMail, _message);

This thread is queued when user clicks on the send button but since this is default Background Thread I was expecting when the page response ended, this thread would be terminated but it didn't happen because the current thread which fires this Thread was also a Background Thread and a Worker Thread, so which means there is an unfinished foreground thread(s) (Could be MainThread or Worker Threads) still alive but I don't know when they finish because their finish time will effect my background worker threads; When the last foreground thread ends, it causes the process to be terminated, so do background threads.

Should I be afraid of this or Asp.NET can handle it automatically and I am kinda confused because I've read a lot of things about it and now everything is mixed up.

Could you please clarify things a little bit ?

Thanks in advance.

+1  A: 

When you call QueueUserWorkItem a new thread will be drawn from the thread pool if available and execute the callback function on this thread. If no threads are available, the function will block until a thread is freed. Once it finishes the execution of the method the thread will be suspended and returned to the pool for further reuse. Your only concern should be the fact that threads from the pool are also used to service requests, so if you perform lengthy tasks on them you could jeopardize the whole system request servicing capabilities because there's a limited number of threads in the pool and if all of them are busy performing lengthy operations future HTTP requests will be queued. As an alternative you could consider creating threads manually: new Thread(state => { }).Start();

Darin Dimitrov
And what about the foreground threads ? Which one is foreground events or main events and how can I know when they occur ?
Braveyard
Creating threads manually is usually frowned upon, especially in an ASP.NET application. If too much threads are created, it will slow your application down considerably.
Tommy Carlier
I am not sure I understand your question. Could you elaborate a little more your scenario?
Darin Dimitrov
@Tommy, I agree with you. In general such tasks should be offloaded from the ASP.NET application into NT services, ...
Darin Dimitrov
@Darin :Thanks for the help but Normally there must be foreground threads working on when requesting a page from the server, right ? So if every thread fetched out of Thread Pool is Background Thread, then where are the foreground threads fired up by Asp.NET run-time itself ? (P.s this question to you,I accidentally asked to Tommy :) )
Braveyard
If you consider a shared hosting environment seldom will you find an option to have a windows service doing your background processing. In such cases you have to resort to other options available which can be controlled from ASP.net itself.
Hemanshu Bhojak
+2  A: 

Using the ThreadPool for long-running tasks will negatively influence the performance of your application (because ASP.NET also uses the ThreadPool to handle incoming requests).

Creating threads manually for each task can also become a problem if too much threads are created.

One technique I've used in the past, is to create a custom ThreadPool when starting the application, and enqueuing tasks on that ThreadPool. A simple custom ThreadPool could consist of a single Thread and a Queue of tasks.

Tommy Carlier
+1  A: 

You can use MSMQ for creating your email queue and have a single thread process the queue.

The following post might be useful as it fits your problem domain. Although it does not use MSMQ but is a good post on processing scheduled tasks using ASP.net.

Simulate a Windows Service using ASP.NET to run scheduled jobs

Hemanshu Bhojak
Well,it could be advanced to my application, mine is a little bit simple to use advanced things I believe :)
Braveyard
I wouldnt call it advanced. It helps solve the problem at hand. Also if you do feel it is advanced you can create a application level variable of type queue and queue objects of type MailMessage and then have your thread process it. It is similar to MSMQ and solves the purpose. But you need to make it thread safe as two threads accessing a single queue can have un desirable effects.
Hemanshu Bhojak
Advantages of using MSMQ is that your queue is not lost in the event of an application crash. You can resume from the last processed item on application restart.
Hemanshu Bhojak
Thank you for your answers. I will give a try :)
Braveyard