Hi Rick,
Thanks for you information and a great article. I do have some other
questions based on the info though:
Thanks for clearing up the 'Cancel thread' bit - setting a flag and exiting
the loop is a lot cleaner.
My confusion seems to be around two areas (in comparison with winform apps):
1. What the scope of threads are when it comes to different users accessing
the website;
[ i.e. are the main website pages/classes all running on ONE thread and
being accessed by multiple users, or does each user that accesses the
website start a new separate thread on the webserver?]
2. The effect of waiting for a thread to complete, based on the above
confusion;
[i.e. does the whole website freeze if the main calling code waits for a
thread to complete? Does it freeze for just the user that started the
'SendEmails' thread or for the entire website for all users?]
My concern also is not so much keeping the 'SendEmails' thread alive, as
much as making sure I don't keep spawning new threads or keeping the thread
alive indefinately because of no timeout and some sort of sending hangup on
the smtp server. Clearly I can't restart a shared web server, like I could
just exit a winform app and all its spawned threads.
Your example has a thread running indefintately - there are reasons why I
don't want to do this - one being that this is only one small function of
the website that may not always be used, so it seems in appropriate to keep
the thread running, and more appropriate to only run it when it is needed.
If I was to use a WaitHandle, which looks similar to the Thread.Wait
approach, in order to have some sort of failsafe timeout and to only update
data when the 'SendEmails' thread has done its job, wouldn't I still need to
do this waiting in new a calling thread (the 'MainSendEmailsThread' thread
that in turn calls the 'SendEmails' thread )?
My thinking being that I wouldn't want the main code to stop and wait -
doesn't this stop other users accessing that class (or the website) too (see
my 'confusion' explanation above)? Having a 'MainSendEmailsThread' and a
'SendEmailsThread' would mean that the 'MainSendEmailsThread' would just set
the 'IsSending' flag then call the 'SendEmailsThread' and wait for its
completion, before doing any tidying up or data updating. That is, the
thread that is 'frozen' whilst waiting is the 'MainSendEmailsThread'
and not the main website code, hence allowing that user and others to
continue viewing pages whilst the two threads are running.
In effect, both threads would only have one instance running as a check
would be made each time a user clicks the 'Send Emails' button to see if the
'IsSending' flag is set. If it is, then the user would be informed the the
function is 'busy', and no threads would be started by that user.
Is this all based on entirely the wrong assumption about asp.net threads, or
am I on the right approach for this senario?
Thanks in advance,
JJ
"Rick Strahl [MVP]" <ri********@hotmail.comwrote in message
news:81**********************************@microsof t.com...
Hi JJ,
>My questions are:
1. If there are some unexpected errors in the SendEmails thread, would
the thread ever end? Should threads always be started with some sort of
timeout - of so how ? Should the thread's code always be in some sort of
try..catch ?
Yes. The Exception will kill the thread. Your best bet is to ensure that
that doesn't happen by wrapping your mainline code into exception
handlers.
>2. To do actions on the database only when the thread finishes, (i.e.
using Thread.Wait()), I assume I have to start a main calling thread
first, which itself will wait for the SendEmails thread to finish before
it does its job?
Look into using WaitHandles (AutoResetEvent works great for this).
Basically you can use these WaitHandles to make a thread wait until
another thread triggers it.
I recently posted a blog entry about creating a basic Scheduler in ASP.NET
here and it demonstrates how you can do this:
http://west-wind.com/weblog/posts/67557.aspx
The code's not quite generic, but close and might give you an idea how you
can run a 'background' thread in ASP.NET whether you're launching it on
app start (as the post does) or whether you explicitly launch it from a
specific page hit.
>3. How can you check if a particular thread is running, whichever user it
was started by, so I don't accidentally try to start another one? (is my
approach with setting a static flag for a particular thread - in this
case 'IsSending' - the best approach?
You can't easily do that at least not reliably. Your best bet is to create
a scheduler that runs - does what it needs to and goes to sleep until the
next request is submitted.
>4. If I was to have a 'Cancel Sending' button, is there any cleaning up
or waiting I need to do (apart from resetting Email.IsSending = false),
or is it just simply Thread.Abort?
Typically you shouldn't call Thread.Abort() as it is a hard reset and
doesn't clean up resources. A better approach for you is probably to check
on every iteration (ie. after each email that's been sent) if the thread
should be cancelled and then simply exit the loop and or method you're
running in.
+++ Rick ---
--
Rick Strahl
West Wind Technologies
www.west-wind.com/weblog