Thread synchronization with EventHandler - c#

I stuck with choosing synchronization primitive.
This is the case:
I have pool of threads, that are in infinitive loop, and waits for some event. And another thread that should invoke this event. When event fires all wating thread should make one iteration and fall back for waiting event again.
Should I use manualResetEvent for this? I can't understand, is there any garanty, that if i wrote in control thread something like this
event.Set();
event.Reset();
All waiting threads make iteration, and all waiting threads makes only one, not two ore three, iterations.
Or should I use another primitive for my case?

Use Monitor.Wait(someObject) in the looping threads, and Monitor.PulseAll(someObject) in the event raising thread.

Related

How to make thread safe event handler

In my application I have a queue which fires notifications whenever there are any changes to the queue, but sometimes it happens that when there are simultaneous operations on the queue event handler that it fires multiple times and that's okay, but what I don't want is,...
Below is the code for the event handler:
private async void NotificationQueue_Changed(object sender, EventArgs e)
{
if (!IsQueueInProcess)
await ProcessQeueue();
}
In ProcessQueue method I am setting IsQueueInProcess to true and whenever it gets completed it is set to false. Now, the problem is that whenever multiple event notifications fire simultaneously multiple ProcessQeueue methods start executing, which I don't want. I want to make sure that there will be only one execution of ProcessQeueue at any given time.
Given your statement that this event is raised whenever there are any changes to the queue, and that the queue can be used concurrently (i.e. there are multiple producers adding things to the queue), it seems likely to me that the best way to address this would be to abandon the event-based behavior altogether. Instead, using BlockingCollection<T>, with a thread dedicated to processing the queue via GetConsumingEnumerable(). That method will block the thread as long as the queue is empty, and will allow the thread to remove and process items in the queue any time any other thread adds something to it. The collection itself is thread-safe, so using that you would not require any additional thread synchronization (for the handling of the queue, that is…it's possible processing an item involves thread interactions, but there's nothing in your question that describes that aspect, so I can't say one way or the other anything about that).
That said, taking the question literally, the simplest approach would be to include a semaphore:
private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1);
private async void NotificationQueue_Changed(object sender, EventArgs e)
{
if (_semaphore.Wait(0))
{
await ProcessQueue();
_semaphore.Release();
}
}
The above attempts to acquire the semaphore's lock. With a timeout of 0 milliseconds, it will return immediately even if the semaphore could not be acquired. The return value indicates whether the semaphore was successfully acquired or not.
In this way, as long as there is no outstanding queue-processing operation, the current event handler invocation can acquire the semaphore and will call the ProcessQueue() method. When that operation completes, the continuation will release the semaphore. Until that happens, no other invocation of the event handler will be able to acquire the semaphore, and thus will not initiate processing of the queue.
I'll note that nothing here guarantees a solution to threads racing with each other that would ensure the queue is always either empty, or always has some processing operation acting on it. That's up to you, to ensure that the ProcessQueue() method has the synchronization needed to guarantee that if any thread has modified the queue and caused this event to be raised, that that thread will not fail to initiate another round of processing should the first round not be able to observe the change.
Or put another way, you need to make sure that for any thread that is going to raise that event, either its change to the queue will be observed by the current processing operation, or that thread will initiate a new one.
There's not enough context in your question for anyone to be able to address that concern specifically. I will just point out that it's a common enough thing for someone to overlook when trying to implement this sort of system. IMHO, all the more reason to just have a dedicated thread using BlockingCollection<T> to consume elements added to the queue. :)
See also the related question How to avoid reentrancy with async void event handlers?. This is a slightly different question, in that the accepted answer causes each invocation of the event handler to result in the operation initiated by the event handler. Your scenario is simpler, since you simply want to skip initiation of a new operation, but you may still find some useful insight there.
I agree with Peter that abandoning event-based notifications is the best solution, and that you should move to a producer/consumer queue. However, I recommend one of the TPL Dataflow blocks instead of BlockingCollection<T>.
In particular, ActionBlock<T> should work quite nicely:
private readonly ActionBlock<T> notificationQueue = new ActionBlock<T>(async t =>
{
await ProcessQueueItem(t);
});
By default, TPL Dataflow blocks have a concurrency limit of 1.

Thread.Sleep(2500) vs. Task.Delay(2500).Wait()

I want some clarity on this. I know that Task.Delay will internally use a Timer and it is obviously task-based (awaitable), whereas Thread.Sleep will cause the thread to be blocked. However, does calling .Wait on the task cause the thread to be blocked?
If not, one would assume that Task.Delay(2500).Wait() is better than Thread.Sleep(2500). This is slightly different that the SO question/answer here as I'm calling .Wait().
Using Wait on an uncompleted task is indeed blocking the thread until the task completes.
Using Thread.Sleep is clearer since you're explicitly blocking a thread instead of implicitly blocking on a task.
The only way using Task.Delay is preferable is that it allows using a CancellationToken so you can cancel the block if you like to.
Thread.Sleep(...) creates an event to wake you up in X millisec, then puts your Thread to sleep... in X millisec, the event wakes you up.
Task.Delay(...).Wait() creates an event to start a Task in X millisec, then puts your Thread to sleep until the Task is done (with Wait)... in X millisec, the event starts the Task which ends immediately and then wakes you up.
Basically, they are both very similar. The only difference is if you want to wake up early from another Thread, you won't hit the same method.

Situation: seperated thread timer invoke UIThread and lock because a Form timer lock object

The situation is as follows: a thread timer (from System.Threading.Timer) runs in an interval and use a object to lock and do something. An UI timer (System.Windows.Forms.Timer) do also thinks on the form by interval and using the same object. So he locks this object also.
Sometimes the thread timer will do invoke the UIThread as follow:
lock (_lockobj)
{
form.Invoke(new MethodInvoker(delegate
{ // Do somethings on form }));
}
The problem is that this call will 'sleep' because the same lock on '_lockobj' is happen by the Form timer (which sleep also). So a deadlock is happen (this is what it is?).
I think it is clearly for me what is happening here but how to solve this. Or is this a design failure? Or maybe there are functions available that help me with this?
Question is: is it maybe possible that a not-UIThread invoking the form when the UIThread is sleeping?
Thanks.
This is clearly a deadlock. You must not call into other thread while holding a lock.
Explanation:
Imagine that the timer thread gets the lock, and is going to call to the UI thread. At the very same moment, the UI thread is trying to obtain the lock, and now waits for it to be released. So return to the first thread: the call into the UI thread cannot finish, because the UI thread is waiting. Deadlock.
My suggestion would be: get rid of all locking, and marshal all the operations into the UI thread. This way your calls are obviously serial (all of them happen in the same thread!), so there's no need for locking.

How to get thread status..in Multi threading

May be it sound dumb but if I want some computed value from other thread and other value from one more thread and this two value in my main thread how can I,if In case second thread completed before first one.it will create problem..so I just want is there any way that I can get the thread status means its still running or stop.
Thanks
Sounds like you want to wait until both threads have finished. Simply call Join on each of them. After the calls have returned, you know that both threads have finished.
Thread class have ThreadState property, but make sure you know about thread synchronization. Here are two articles:
http://msdn.microsoft.com/en-us/library/dsw9f9ts%28VS.71%29.aspx
http://msdn.microsoft.com/en-us/magazine/cc188793.aspx
Thread.ThreadState or Thread.Join if you want to wait for your threads. Or use Semaphore

Anyway to detect if a threaded method has completed

I've got a queue, which is basically the producer/consumer queue in the albahari.com
threading book, which takes an queue item off the queue, which is an action execution block off the queue and then calls a method to execute the actionlist within the queue item.
I can kill the queue easily enough by enqueing a null actionblock and block the main thread by doing a spin/wait with a thread.sleep() until the queue count goes to zero, and all the threads fall through the while !=null loop, thereby completing, but the method executing the last actionlist may still be executing the last thread.
Question is, is their anyway to detect if that method still has a thread executing it, like maybe using a Semaphore or counter with an Interlock to count the semaphore up at the beginning of the method and count it down at the end. So if it reaches zero, them I know its not threaded.
This is the implementing a destroy method on the interface, to close it down before calling dispose.
Use the Backgroundworker which has a completed event
If you start a thread like this:
System.Threading.Thread mythread = new System.Threading.Thread();
mythread.Start();
You can check:
mythread.IsAlive()
at any point to determine its status.
Use a PostSharp attribute on the method.

Categories