【发布时间】:2021-02-26 14:04:16
【问题描述】:
我有一个简单的ITimer 接口,它只有一个经典的Elapsed .NET 事件,该事件在特定时间跨度后引发。
interface ITimer
{
void Start(TimeSpan interval);
void Stop();
public event EventHandler Elapsed;
}
现在我想创建一个类似于Task.Delay(TimeSpan) 的功能,但它应该使用ITimer 抽象而不是“实时”时间。也不同于Task.Delay(TimeSpan) 我虽然返回ValueTask 而不是Task 可能是个好主意,因为它可以实现无分配并且通常可能更高性能。无论如何,延迟的完成也只需要等待一次。
现在一个有点幼稚的实现可能看起来像这样。这里的问题是,使用ValueTask 根本没有任何好处。这样的实现怎么会充分利用ValueTask 所承诺的(便宜且无需分配)。
ValueTask Delay(TimeSpan duration, CancellationToken cancellationToken)
{
// We get the ITimer instance from somwhere, doesn't matter for this question.
ITimer timer = timerFactory.Create();
var tcs = new TaskCompletionSource<bool>();
timer.Elapsed += (_, __) => { tcs.SetResult(true); };
cancellationToken.Register(() =>
{
timer.Stop();
throw new OperationCanceledException();
});
timer.Start(duration);
return new ValueTask(tcs.Task);
}
【问题讨论】:
-
我希望这个方法在你调用它时永远不会完成,所以这会比仅仅返回一个
Task更糟糕。 -
对不起,我不明白你的意思。
-
“过早的优化真的是万恶之源” (Donald Knuth)。我会非常小心地优化这样的事情,没有充分的理由相信这是一个实际问题。
标签: c# .net-core taskcompletionsource valuetask