سؤال

I'm trying to do something like this:

EventWaitHandle handler = new EventWaitHandle(false, EventResetMode.AutoReset)

//This code will run in background thread
private void AsyncWait() {
    while (true) {
        handler.WaitOne();
        //LongRunningOperation()
    }
}

Elsewhere in the code, there will be methods that call:

handler.Set()

So the LongRunningOperation() is executed..

Problem is, the handler.Set() can be called again while the AsyncWait() thread is running the LongRunningOperation()

This makes the LongRunningOperation() will never be called whenever the handler.Set() is called while AsyncWait() is still executing LongRunningOperation()

How to make this right? :(

هل كانت مفيدة؟

المحلول

Use a Semaphore instead of AutoResetEvent.

A semaphore uses a counter internally. You can also define the maximum number of threads that can be "let through" at a time.

readonly Semaphore _semaphore = new Semaphore(0, int.MaxValue);

public void Enqueue<T>(T item)
{
     _internalQueue.Enqueue(item);
     _semaphore.Release();  // Informs that deque task to unblock if waiting. Equivalent to the  WaitHandle.Set() method. Increases the semaphore counter
}

public T Dequeue()
{
     _semaphore.WaitOne();   // Blocks as long as there are no items in the queue. Decreases the semaphore counter when "let through". Blocks the thread as long as semaphore counter is zero.
     return _internalQueue.Dequeue();
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top