在给定超时后,CancellationTokenSource不会取消任务

时间:2016-02-10 18:00:37

标签: c# .net task-parallel-library

我正在学习TAP,我喜欢使用单元测试来探索TPL数据流。我有以下一个我无法理解的内容:

var cts = new CancellationTokenSource(500);
var tcs = new TaskCompletionSource<bool>(cts.Token);
var agent = new ActionBlock<FakeMessage>( async evt =>
{
    await Task.Delay(5000);
    tcs.SetResult(true);
});

agent.Post(new FakeMessage());
try
{
    var result = await tcs.Task;
    Assert.Fail();
}
catch (OperationCanceledException ex)
{
    Assert.IsTrue(true);
}
catch (Exception e)
{
    Assert.Fail();
}

我原本期望它提高第一行定义的超时并捕获OperationCanceledException,但我总是以Assert.Fail后面的await tcs.Task结束。有人能解释一下我的假设是不是很顺利吗?

1 个答案:

答案 0 :(得分:2)

TaskCompletionSource不接受CancellationToken

它接受Object状态,您可以在技术上将CancellationToken传递给它,但它不会做任何事情,尤其是不取消TaskCompletionSource

如果你想取消TaskCompletionSource,你可以通过一个简单的超时来做到这一点:

Task.Delay(500).ContinueWith(t => tcs.SetCancelled());

您还可以创建接受TaskCompletionSource的{​​{1}},并在取消CancellationToken时取消自己:

TaskCompletionSource