我有一个工作线程,该线程使用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()
调用以退出它?
答案 0 :(得分:1)
您可以使用WaitHandle.WaitAny
静态方法:
WaitHandle.WaitAny(new[] { autoResetEvent, cancellationToken.WaitHandle }, 1000);
但是,访问CancellationToken.WaitHandle
有一个弊端:
访问此属性将导致WaitHandle实例化。最好仅在必要时使用此属性,然后尽早处置关联的CancellationTokenSource实例(处置源将处置此分配的句柄)。手柄不应关闭或直接丢弃。