首页 > 解决方案 > 等待两个同步对象

问题描述

我有一个工作线程,它使用 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()调用以便它可以退出?

标签: c#.netconcurrencytask

解决方案


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

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

但是,访问有一个缺点CancellationToken.WaitHandle

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


推荐阅读