bit*_*onk 2 c# task-parallel-library async-await taskcompletionsource
a TaskCompletionSource和它Task如果TaskCompletionSource永远不会完成会发生什么(即SetCancelled,SetException或者SetResult永远不会被调用?它会Task永远存在,因为它永远不会完成吗?
在下面的例子中,我有一个参数化测试的简化版本.如果超时(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);
}
Run Code Online (Sandbox Code Playgroud)
虽然我们在这里,有什么方法可以改进上面的测试(例如,使它更简洁/简单/可读)?
我是否需要进行任何类型的清理(例如确保
tcs.SetCancelled()被调用)?
使用a TaskCompletionSource<T>不需要任何清理.事实上,它甚至不承认任何清理.所以你的问题的答案是"不".
这TaskCompletionSource<T>只是一个概念上简单的数据结构,允许您最多输入一个东西(类型T,异常或取消的结果).它的Task属性暴露了一个Task<T>只是这个承诺的单一事物的包装,将TaskCompletionSource<T>在未来的某个时间推进.它不使用任务池.
永远不要把任何东西推到一个TaskCompletionSource<T>是完全有效的.这恰好对应于一个Task<T>将永远"运行"并永远不会完成的东西.
| 归档时间: |
|
| 查看次数: |
715 次 |
| 最近记录: |