Write your own async method

Actual Answer

You do that using TaskCompletionSource, which has a Promise Task that doesn’t execute any code and only:

“Represents the producer side of a Task unbound to a delegate, providing access to the consumer side through the Task property.”

You return that task to the caller when you start the asynchronous operation and you set the result (or exception/cancellation) when you end it. Making sure the operation is really asynchronous is on you.

Here is a good example of this kind of root of all async method in Stephen Toub’s AsyncManualResetEvent implementation:

class AsyncManualResetEvent 
{ 
    private volatile TaskCompletionSource<bool> _tcs = new TaskCompletionSource<bool>();

    public Task WaitAsync() { return _tcs.Task; } 
    public void Set() { _tcs.TrySetResult(true); } 
    public void Reset() 
    { 
        while (true) 
        { 
            var tcs = _tcs; 
            if (!tcs.Task.IsCompleted || 
                Interlocked.CompareExchange(ref _tcs, new TaskCompletionSource<bool>(), tcs) == tcs) 
                return; 
        } 
    } 
}

Background

There are basically two reasons to use async-await:

  1. Improved scalability: When you have I/O intensive work (or other inherently asynchronous operations), you can call it asynchronously and so you release the calling thread and it’s capable of doing other work in the mean time.
  2. Offloading: When you have CPU intensive work, you can call it asynchronously, which moves the work off of one thread to another (mostly used for GUI threads).

So most of the .Net framework’s asynchronous calls support async out of the box and for offloading you use Task.Run (as in your example). The only case where you actually need to implement async yourself is when you create a new asynchronous call (I/O or async synchronization constructs for example).

These cases are extremely rare, which is why you mostly find answers that

“Only explains it with already existing methods and just using async/await pattern”


You can go deeper in The Nature of TaskCompletionSource

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)