How to create and use custom awaitable in c #?

I am trying to implement a custom awaitable to execute await Thread.SleepAsync() without creating any additional threads.

Here is what I have:

  class AwaitableThread : INotifyCompletion { public AwaitableThread(long milliseconds) { var timer = new Timer(obj => { IsCompleted = true; }, null, milliseconds, Timeout.Infinite); } private bool isCompleted = false; public bool IsCompleted { get { return isCompleted; } set { isCompleted = value; } } public void GetResult() {} public AwaitableThread GetAwaiter() { return this; } public void OnCompleted(Action continuation) { if (continuation != null) { continuation(); } } } 

And this is how the dream will work:

  static async Task Sleep(int milliseconds) { await new AwaitableThread(milliseconds); } 

The problem is that this function returns immeasurably, although in OnCompleted , IsCompleted is still false.

What am I doing wrong?

+4
source share
1 answer

Fully implement the expected template for use in production - a complex business - you need, in particular, to capture the execution context. Steven Tub 's blog post on this is much more detailed. In many cases, it is easier to provide feedback on a Task<T> or Task , potentially using a TaskCompletionSource . For example, in your case, you can write the equivalent of Task.Delay as follows:

 public Task MyDelay(int milliseconds) { // There only a generic TaskCompletionSource, but we don't really // care about the result. Just use int as a reasonably cheap version. var tcs = new TaskCompletionSource<int>(); Timer timer = new Timer(_ => tcs.SetResult(0), null, milliseconds, Timeout.Infinite); // Capture the timer variable so that the timer can't be garbage collected // unless the task is (in which case it doesn't matter). tcs.Task.ContinueWith(task => timer = null); return tcs.Task; } 

Now you can await complete this task, as you can expect the result of Task.Delay .

+10
source

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


All Articles