C# 使用 BlockingCollection 正确中止总是 运行 的线程
C# Correctly aborting a always running thread with a BlockingCollection
我是 运行 一个拥有
的线程
while(isRunning)
{
blockingCollection.Take()
}
首先我将 isRunning
设置为 false。然后我调用 thread.Interrupt
来阻止 blockingCollection
等待新项目。之后,我为 class 运行 catch 块中的线程调用 Dispose
方法。
这是 best/correct 的方法吗?
BlockingCollection 具有 CompleteAdding() 方法并完全支持 Cancellation。
while(isRunning && ! blockingCollection.IsCompleted)
{
isRunning = blockingCollection.TryTake(out someThing, -1, cancelToken);
}
这样你可以而且应该让线程正常结束,总是更好的选择。
根据 Henk 的回答,如果您希望拥有 Take() 的阻塞能力,但需要在它等待空列表时取消,您可以通过这种方式在循环外处理取消。
private void DoSomething(CancellationToken token)
{
while (IsRunning)
{
MyObject next;
try
{
next = _queue.Take(token);
}
catch(OperationCanceledException)
{
break; //Cancelled
}
// Do something with 'next'
}
// Cleanup
}
然后,当 'whatever' 发生需要您终止此循环时,即使列表为空并且它卡在 Take() 调用上阻塞,也只需在生成代币.
注意 - 为了安全起见,可能还建议捕获 Take() 也可能抛出的 ObjectDisposedException。查看文档以了解有关它的详细信息以及它可能抛出的原因。
我是 运行 一个拥有
的线程while(isRunning)
{
blockingCollection.Take()
}
首先我将 isRunning
设置为 false。然后我调用 thread.Interrupt
来阻止 blockingCollection
等待新项目。之后,我为 class 运行 catch 块中的线程调用 Dispose
方法。
这是 best/correct 的方法吗?
BlockingCollection 具有 CompleteAdding() 方法并完全支持 Cancellation。
while(isRunning && ! blockingCollection.IsCompleted)
{
isRunning = blockingCollection.TryTake(out someThing, -1, cancelToken);
}
这样你可以而且应该让线程正常结束,总是更好的选择。
根据 Henk 的回答,如果您希望拥有 Take() 的阻塞能力,但需要在它等待空列表时取消,您可以通过这种方式在循环外处理取消。
private void DoSomething(CancellationToken token)
{
while (IsRunning)
{
MyObject next;
try
{
next = _queue.Take(token);
}
catch(OperationCanceledException)
{
break; //Cancelled
}
// Do something with 'next'
}
// Cleanup
}
然后,当 'whatever' 发生需要您终止此循环时,即使列表为空并且它卡在 Take() 调用上阻塞,也只需在生成代币.
注意 - 为了安全起见,可能还建议捕获 Take() 也可能抛出的 ObjectDisposedException。查看文档以了解有关它的详细信息以及它可能抛出的原因。