[英]Task.Delay(0) not asynchronous
I have the following code (yes, I could be simulating JavaScript setTimeout
api) 我有以下代码(是的,我可以模拟JavaScript setTimeout
api)
async void setTimeout(dynamic callback, int timeout)
{
await Task.Delay(timeout);
callback();
}
It looks like for timeout > 0
, the setTimeout
works asynchronously wherein the control is returned back to the callee
on await
and callback
is invoked after the task runs asynchronously. 看起来对于timeout > 0
, setTimeout
异步工作,其中控件在await
返回给callee
,并且在任务异步运行后调用callback
。 BUT when timeout == 0
, the function behaves in a synchronous manner (code always run past the await line in the same thread without a context switch). 但是当timeout == 0
,该函数以同步方式运行(代码总是在没有上下文切换的同一线程中经过await行)。 On further digging, it turns out that Task.Delay
is implemented to behave this way ( Task.Yield() versus Task.Delay(0) ) 在进一步挖掘时,事实证明Task.Delay
实现为以这种方式运行( Task.Yield()与Task.Delay(0) )
Wondering if there is a way to make Task.Delay(0) asynchronous or an alternate solution to make my setTimeout
function asynchronous when timeout
is 0
? 想知道是否有办法使Task.Delay(0)异步或另一种解决方案使我的setTimeout
函数在timeout
为0
时异步? ( so that I could mimic JavaScript setTimeout
functionality ) I see discussions on using Task.FromResult(true)
or Task.WhenAll
, but they don't seem to work. ( 这样我就可以模仿JavaScript setTimeout
功能 )我看到有关使用Task.FromResult(true)
或Task.WhenAll
,但它们似乎不起作用。
Indeed I can use Task.Delay(1)
instead of Task.Delay(0)
but it does not look organic. 事实上,我可以使用Task.Delay(1)
而不是Task.Delay(0)
但它看起来不是有机的。
The reason Task.Delay(0)
does not run asynchronously is because the async-await state machine explicitly checks whether the task is completed and if it is, it runs synchronously. Task.Delay(0)
不异步运行的原因是因为async-await状态机显式检查任务是否已完成,如果是,则它同步运行。
You can try using Task.Yield() , which will force the method to return immediately and resume the rest of the method on the current SynchornizationContext
. 您可以尝试使用Task.Yield() ,它将强制该方法立即返回并在当前的SynchornizationContext
上恢复该方法的其余部分。 eg: 例如:
async void setTimeout(dynamic callback, int timeout)
{
if(timeout > 0)
{
await Task.Delay(timeout);
}
else
{
await Task.Yield();
}
callback();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.