I am not sure which strategy to adopt...I am focusing on my operation getting completed, but I'd also like to keep performance issues to a min too...there is a method called Execute() which has to wait (run synchronously) until an operation completes. This operation happens on another thread. There are 2 ways to implement the same thing...
By using ManualResetEvent
void Execute()
{
taskHandle = new ManualResetEvent(false);
.
.
//delegate task to another thread
.
.
taskHandle.WaitOne();
}
By using a simple while construct
void Execute()
{
.
.
//delegate task to another thread
.
.
while (!JobCompleted)
Thread.Sleep(1000);
}
Which one of the two approaches should I adopt...why?
EDIT:
Q2. What if I just had an empty while contruct? Whats the difference...?
while(!JobCompleted);
EDIT: (something I gathered before)
http://www.yoda.arachsys.com/csharp/threads/waithandles.shtml - This article says manualresets are comparitively slower because they go out of managed code and back in...
Out of curiosity, why ManualResetEvent
and not AutoResetEvent
? Either way, go with the OS primitive over a sleep-check-sleep approach.
You could also use a Monitor
lock (either explicitly through Monitor.Enter
and Monitor.Exit
, or through a lock
block), but the approach should be based upon what you're actually doing; if it's a scenario of "there's only one of these things and I need exclusive access", then use a Monitor
lock. If it's "I need to wait until the other thread finishes for reasons other than resource access", then use an AutoResetEvent
or ManualResetEvent
.
The suggestions to use Thread.Join
are good if (and only if)
Thread
objectIf either isn't true (you don't have access, or the other thread won't terminate, it will just signal an "all clear") then Thread.Join
isn't viable.
The worst option is
while(!JobCompleted);
As that will tie up the processor with needless checks of the variable without any pause in between them. Yes, it will block your thread until the operation completes, but you'll max out CPU usage (or at least a single core's worth).
The event makes more efficient use of the processors- you're not having to wake the parent thread up to poll. The kernel will wake you up when the event fires.
If you have access to the original Thread object, or can get that access, you're best off using Thread.Join()
.
Edit: Also, if this is taking place in a GUI like WinForms or WPF, you may want to consider using BackgroundWorker
The main disadvantage to using Thread.Sleep()
is that you are making the decision on how long the thread will wait. The operation you are waiting for may take more or less time, and in general, it is very difficult to precisely quantify that time. If the thread sleeps too long, then you are not making best use of system resources.
In order to be optimal, you should use ManualResetEvent
(or AutoResetEvent
) so that your thread is resumed as soon as the dependent operation finishes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With