我正在尝试创建一个异步ProducerConsumerCollection,为此,我正在使用此msdn页面(http://msdn.microsoft.com/zh-cn/library/hh873173.aspx(页面底部))。
我现在正在尝试添加超时,这是我的工作:
public async Task<T> TakeWithTimeout(int timeout)
{
Task<T> takeTask = this.Take();
if (timeout <= 0 || takeTask == await Task.WhenAny(this.tasks.Take(), Task.Delay(timeout)))
{
return await takeTask;
}
else
{
// Timeout
return default(T);
}
}
}
Run Code Online (Sandbox Code Playgroud)
此代码的问题在于,在超时的情况下,它不会取消Take()方法创建的任务。
由于此任务是由TaskCompletionSource“创建”的,因此我不能给它一个CancellationToken吗?
因此,如何继续取消它并正确实现此Take with timeout?
谢谢 :)
编写取消安全async
友好的生产者/消费者集合并非易事。您需要做的是更改Take
以接受a CancellationToken
作为参数,并且它应该注册一个处理程序,以便在取消处理程序时将其TaskCompletionSource
取消。
我强烈建议您使用BufferBlock<T>
,它具有内置的取消支持。
如果您不能使用TPL数据流(例如,您在PCL中工作,或者数据流不支持目标平台),则可以使用开源AsyncEx库(例如AsyncProducerConsumerQueue
或AsyncCollection
)中的生产者/消费者集合。这些都基于AsyncLock
和AsyncConditionVariable
,我在自己的博客中简要介绍了该设计(该设计未涉及取消详细信息)。支持采用这种设计的生产者/消费者集合中的取消的关键是要支持中的取消AsyncConditionVariable.WaitAsync
;一旦您的条件变量类型支持取消,那么您的集合也将轻松支持它。
归档时间: |
|
查看次数: |
5730 次 |
最近记录: |