Task.Delay (0) is not asynchronous

I have the following code (yes, I could simulate a JavaScript setTimeout api)

  async void setTimeout(dynamic callback, int timeout) { await Task.Delay(timeout); callback(); } 

It seems that for timeout > 0 , setTimeout works asynchronously when the control returns back to callee on await and the callback is called asynchronously after the task is completed. BUT , when timeout == 0 , the function behaves synchronously (the code always passes the wait line in the same thread without a context switch). Upon further digging, it turns out that Task.Delay is implemented in such a way as to behave this way ( Task.Yield () compared to Task.Delay (0) )

It's amazing if there is a way to make Task.Delay (0) asynchronous or an alternative solution to make my setTimeout function asynchronous when timeout is 0 ? (so that I could mimic the functionality of JavaScript setTimeout ). I see discussions about using Task.FromResult(true) or Task.WhenAll , but they don't seem to work.

In fact, I can use Task.Delay(1) instead of Task.Delay(0) , but it does not look organic.

+5
source share
1 answer

Cause Task.Delay(0) not executed asynchronously, since the state machine with asynchronous wait explicitly checks whether the task is completed and if it is, it runs synchronously.

You can try Task.Yield () , which will make the method return immediately and resume the rest of the method in the current SynchornizationContext . eg:

 async void setTimeout(dynamic callback, int timeout) { if(timeout > 0) { await Task.Delay(timeout); } else { await Task.Yield(); } callback(); } 
+9
source

Source: https://habr.com/ru/post/1234760/


All Articles