我有一个情况,我的代码正在等待一些时间延迟:
await Task.Delay(10_000, cancellationToken);
在某些情况下,即使超时尚未到期,我也希望立即继续执行(“跳过延迟”)。可以在代码已等待延迟的情况下做出这个决定。
我不想做的事情:根据条件循环
foreach (var i = 0; i < 10 && !continueImmediately; i++)
{
await Task.Delay(1000, cancellationToken);
}
由于存在一定的延迟(这里是1秒)或者不必要地唤醒,我不希望发生以下行为:
取消
var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken)
try
{
await Task.Delay(1000, linkedTokenSource.Token);
}
catch (OperationCancelledException)
{
// determine if the delay was cancelled by the cancellationToken or by the delay shortcut...
}
因为我想避免异常情况。
我的想法:
TaskCompletionSource tcs = new TaskCompletionSource();
await Task.WhenAny(new[] { tcs.Task, Task.Delay(10_000, cancellationToken) });
为了缩短延迟时间: tcs.SetResult()
。
这似乎可行,但我不确定是否有任何清理工作遗漏。例如,如果采取了快捷方式(即因 tcs.Task
而完成 WhenAny),Task.Delay
是否会继续消耗资源?
注意:我确实喜欢取消支持,但这不是我的问题,因此您可以忽略我问题中的所有 cancellationTokens。
Task.Delay
会“运行”呢?它的目的是允许一个任务在稍后变成已发出信号,而不会毫无意义地占用一个线程。 - Damien_The_UnbelieverTask.WhenAny
有什么意义呢?如果你不想等待,请不要调用Task.Delay()
:if (!shortcut){ await Task.Delay();}
。如果你想要yield,请使用await Task.Yield()
,例如await shortcut?Task.Yield():Task.Delay(1000);
。 - Panagiotis KanavosTask.Delay(...).ContinueWith(_=>{});
。 - Panagiotis Kanavos