4

如果a从未完成(即,或从未被调用), aTaskCompletionSource和它会发生什么?因为它永远不会完成,它会永远存在吗?TaskTaskCompletionSourceSetCancelledSetExceptionSetResultTask

在下面的示例中,我有一个参数化测试的简化版本。如果超时(MyEevent未在 1000 毫秒内调用),则TaskCompletionSource( tcs) 永远不会完成。我有很多这样的测试。我是否需要进行任何类型的清理(例如确保调用 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);
}

当我们这样做时,有什么办法可以改进上述测试(例如,使它更简洁/简单/可读)?

4

1 回答 1

7

我是否需要进行任何类型的清理(例如确保tcs.SetCancelled()被调用)?

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

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

永远不要将任何东西推入 aTaskCompletionSource<T>是完全有效的。这仅对应于Task<T>将永远“运行”并且永远不会完成的。

于 2014-12-02T16:58:18.967 回答