等待两个同步对象

时间:2018-07-16 20:32:26

标签: c# .net concurrency task

我有一个工作线程,该线程使用AutoResetEvent来确定队列是否已被修改,并使用CancellationToken来确定队列是否已被取消。

ConcurrentQueue queue = new ConcurrentQueue<MyClass>();

static private void Worker()
{
    while (true) 
    {
        while (queue.Count > 0)
        {
            MyClass item;
            if (queue.TryDequeue(out item))
            {
                item.DoWork();
            }
        }
        autoResetEvent.WaitOne(1000);  //Wait for item to be added to queue
        cancellationToken.ThrowIfCancellationRequested();  //Check if cancelled
    }
}

上述问题是,即使已经发出取消令牌,对WaitOne()的调用仍将继续阻塞。在这种情况下,我的超时时间为1秒,因此主线程最终将等待一秒钟,然后任务才能尝试完成并退出。

是否有一种方法可以重写它,以便用信号通知取消令牌将允许工作线程通过WaitOne()调用以退出它?

1 个答案:

答案 0 :(得分:1)

您可以使用WaitHandle.WaitAny静态方法:

WaitHandle.WaitAny(new[] { autoResetEvent, cancellationToken.WaitHandle }, 1000);

但是,访问CancellationToken.WaitHandle有一个弊端:

  

访问此属性将导致WaitHandle实例化。最好仅在必要时使用此属性,然后尽早处置关联的CancellationTokenSource实例(处置源将处置此分配的句柄)。手柄不应关闭或直接丢弃。