我应该总是完成TaskCompletionSource吗?

4
如果未完成 TaskCompletionSource(即未调用 SetCancelledSetExceptionSetResult),那么会发生什么?Task 是否因为从未完成而永远存在?
在下面的示例中,我有一个参数化测试的简化版本。如果超时(MyEevent 在 1000ms 内未被调用),则 TaskCompletionSourcetcs)将永远未完成。我有很多类似这样的测试。我需要进行任何清理吗(例如确保调用了 tcs.SetCancelled())?
[Theory]
[InlineData("aa")]
[InlineData(2)]
[InlineData(true)]
[InlineData(null)]
public async Task RaiseMyEvent_RaisesMyEvent_WithOriginalValue(object value)
{
    var sut = new Thing();
    var tcs = new TaskCompletionSource<object>();
    sut.MyEvent += (_, args) => tcs.SetResult(args.Value);

    sut.RaiseMyEvent(value);

    tcs.Task.Should().BeSameAs(await Task.WhenAny(Task.Delay(1000), tcs.Task), "MyEvent should be raised within 1000ms");
    tcs.Task.Result.Should().Be(value);
}

顺便问一下,有没有办法改进上面的测试(例如,更加简洁/简单/易读)?

1个回答

7

我需要进行任何清理吗(例如确保调用tcs.SetCancelled())?

使用TaskCompletionSource<T>不需要任何清理。事实上,它甚至不允许任何清理。所以你的问题的答案是“不需要”。

TaskCompletionSource<T>只是一个概念上简单的数据结构,允许你最多推入一个东西(类型为T的结果、异常或取消)。它的Task属性公开了一个Task<T>,它只是一个包装器,围绕这个承诺的单个事物,在将来的某个时间被推入到TaskCompletionSource<T>中。它不使用任务池。

从不向TaskCompletionSource<T>推入任何内容是完全有效的。这只是对应于一个永远运行并永远无法完成的Task<T>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接