簡體   English   中英

給定超時后,CancellationTokenSource不會取消任務

[英]CancellationTokenSource does not cancel task after given timeout

我正在學習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 ,但是在await tcs.Task之后,我總是以Assert.Fail await tcs.Task 有人可以解釋一下我的假設進行得不好嗎?

TaskCompletionSource不接受CancellationToken

它確實接受Object狀態,並且您可以從技術上將CancellationToken傳遞給它,但是它不會做任何事情,尤其是不要取消TaskCompletionSource

如果要取消TaskCompletionSource ,則可以通過簡單的超時來完成:

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

您還可以創建一個TaskCompletionSource ,它接受CancellationToken並在取消TaskCompletionSourceTaskCompletionSource取消:

class TaskCompletionSourceWithCancellation<T> : TaskCompletionSource<T>
{
    public CancellationToken CancellationToken { get; }

    public TaskCompletionSourceWithCancellation(CancellationToken cancellationToken)
    {
        CancellationToken = cancellationToken;
        var cancellationTokenRegistration =
            cancellationToken.Register(
                _ => ((TaskCompletionSourceWithCancellation<TResult>)_).TrySetCanceled(),
                this);
        Task.ContinueWith(_ => cancellationTokenRegistration.Dispose());
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM