Re: Basic Mutlithreading Questions
- From: "Alvin Bruney [MVP]" <some guy without an email address>
- Date: Wed, 23 May 2007 19:30:12 -0400
I have a thread whose job is to send several emails (i.e. a long task that
mustn't be run by more that one user at a time).
It all works fine, but I am concerned about the lifetime of a thread in
the case of smtp errors, and how it will work with several users trying to
run the same process.
Email servers are async in nature, you are forcing a queue mechanism. This
is bad, very bad.
Another thing, did I mention that this was bad?
Several static variables are written to by the main calling code (the mainBad. very bad. Your main application will essential block your calling
app) and then by the 'SendEmails' thread, in the following manner:
threads with the writer lock. If the writer lock chokes, you don't have an
exception block, your application will hang. Even if it doesn't hang, it
will slow to a crawl as load increases.
Additionally, you sit and wait for a lock for how ever long it takes. Let's
say it takes 23 minutes to acquire that lock, your user is sitting there for
23 minutes looking at a busy page. So they close the browser and come back
in again, the lock is still there. But now, two requests are waiting on a
lock. Lock set to infinite time out - bad idea.
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 ?
I think you know the answers to those questions.
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?
No, you can synchronize the threads which will essential mirror a wait
behavior. There are some wait states that are more efficient than others so
you may want to look at those. However, this is the least of your problems.
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?
No. When you start a thread, don't throw away the handle to the thread. Keep
it, so you can use it to inquire about the state of the thread. In that
case, it is variable thread.IsRunning (if memory serves me correctly)
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?
Here is the thing with thread.abort. Say you have a moving car and you want
to bring it to a halt, you can drive it into a brick wall to stop it, or you
can use the brake pedal. Both get the job done, one does so more *elegantly
than the other. Use a flag to signal your thread to stop.
--
Regards,
Alvin Bruney
------------------------------------------------------
Shameless author plug
Excel Services for .NET is coming...
https://www.microsoft.com/MSPress/books/10933.aspx
OWC Black Book www.lulu.com/owc
Professional VSTO 2005 - Wrox/Wiley
"JJ" <abc@xxxxxxx> wrote in message
news:eyWeoPtmHHA.3872@xxxxxxxxxxxxxxxxxxxxxxx
I've done a little multi-threading on winform apps some time ago now, so
I'm not a complete beginner, but best assume I am for any explanations..:
This is an asp.net 2.0 website, using c#:
I have a thread whose job is to send several emails (i.e. a long task that
mustn't be run by more that one user at a time).
It all works fine, but I am concerned about the lifetime of a thread in
the case of smtp errors, and how it will work with several users trying to
run the same process.
The thread is started like:
ParameterizedThreadStart pts = new ParameterizedThreadStart(SendEmails);
Thread thread = new Thread(pts);
thread.Name = "SendEmails";
thread.Priority = ThreadPriority.BelowNormal;
thread.Start(parameters);
Several static variables are written to by the main calling code (the main
app) and then by the 'SendEmails' thread, in the following manner:
Lock.AcquireWriterLock(Timeout.Infinite);
Email.SentMails = 0;
Email.IsSending = true;
Lock.ReleaseWriterLock();
I am therefore assuming that if another user is viewing the pages and
tries to run the email sending process, I can check to see if the
Email.IsSending is set and if it is, don't allow the 'SendEmails' thread
to be run and present a 'busy' page. Does this sound correct?
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 ?
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?
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?
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?
Sorry for the numerous questions,
JJ
.
- References:
- Basic Mutlithreading Questions
- From: JJ
- Basic Mutlithreading Questions
- Prev by Date: Re: code samples on MSDN don't make sense and not useful sometimes
- Next by Date: Web Deployment Projects (Remote server)
- Previous by thread: Re: Basic Mutlithreading Questions
- Next by thread: ASP.net and IEditableObject
- Index(es):
Relevant Pages
|