Implement async, await, and asyncawait by yourself

Source: Internet
Author: User

Implement async, await, and asyncawait by yourself

I have read some blog posts that I want to try asynchronous operations on my own:

1) directly use the Task (not to mention, this is the standard implementation method provided by Microsoft ).

2)INotifyCompletion interface must be inheritedAnd implement it by yourselfIsCompleted (required)And Result (optional ),GetResult (required)AndOnCompleted (required)Method:

The following is a specific example (self-implemented asynchronous function ):

public interface IAwait<out T> : INotifyCompletion    {        bool IsCompleted { get; }        T Result { get; }        T GetResult();    }    public interface IAwaitable<out T>    {        IAwait<T> GetAwaiter();    }    public class AwaitableFunc<T> : IAwaitable<T>    {        private Func<T> fun = null;        public IAwait<T> GetAwaiter()        {            return new InnerAwaitableImplement(fun);        }        public AwaitableFunc(Func<T> func)        {            fun = func;        }        private class InnerAwaitableImplement : IAwait<T>        {            private Func<T> fun = null;            private bool isFinished=false;            private T result = default(T);            public InnerAwaitableImplement(Func<T> func)            {                fun = func;            }            public bool IsCompleted            {                get                {                    return isFinished;                }            }            public T Result            {                get                {                    return GetResult();                }            }            public void OnCompleted(Action continuation)            {                ThreadPool.QueueUserWorkItem(obj =>                 {                    isFinished = true;                    continuation();                }, null);            }            public T GetResult()            {                result = fun();                return result;            }        }    }

The GetResult and Result attributes should be synchronized (blocking threads ),OnCompleted implements asynchronous methods (new threads are required for processing). In this case, once the main program is called as follows:

AwaitableFunc <int> afunc = new AwaitableFunc <int> () => {// simulate a long task. Note that if a synchronization machine is used, the Thread will die. sleep (5000); return 1 ;}); var result = afunc. getAwaiter (); result. onCompleted () => {MessageBox. Show (result. GetResult (). ToString ());});

You will find that the GetAwaiter method will be executed first to determine whether IsCompleted is false. If it is false, the OnCompleted method will be executed first (as the same as the callback function) and reserved first, then open up a new thread to execute GetResult (), and finally call back to OnCompleted to execute the callback function.

You can also call:

Private async void button#click (object sender, EventArgs e) {AwaitableFunc <int> afunc = new AwaitableFunc <int> () =>{// simulate a long task, note that if the synchronous machine is used, the Thread will die. sleep (5000); return 1 ;}); var result = await afunc;MessageBox. Show (result. ToString ());}

Similar to the first example (It is pointed out that the essence of await is actually a callback function. The Compiler automatically includes all the things in await. It briefly describes the principle. Pay attention to the red part in the code!).

In fact, GetResult is not necessarily required. For example, if the latency of int is arbitrary (the Task. Delay method is not directly called, write it yourself ):

public class TimeDelay    {        private int _delayTime = 0;        public TimeDelay(int delayNumber)        {            _delayTime = delayNumber;        }        public InnerAwaitableImplement GetAwaiter()        {            return new InnerAwaitableImplement(_delayTime);        }        public class InnerAwaitableImplement:INotifyCompletion        {            private int _delayTime = 0;            private bool isFinished=false;            public InnerAwaitableImplement(int delayTime)            {                _delayTime = delayTime;            }            public bool IsCompleted            {                get                {                    return isFinished;                }            }            public void OnCompleted(Action continuation)            {                ThreadPool.QueueUserWorkItem(obj =>                 {                    Thread.Sleep(_delayTime);                    isFinished = true;                    continuation();                }, null);            }            public void GetResult()            {                            }        }    }

This method is used as follows:

private async void button1_Click(object sender, EventArgs e)        {            TimeDelay afunc = new TimeDelay(2500);            await afunc;            MessageBox.Show("OK");        }

Simpler -- Extension Method:

public class TimeDelay    {        private int _delayTime = 0;        public TimeDelay(int delayNumber)        {            _delayTime = delayNumber;        }        public InnerAwaitableImplement GetAwaiter()        {            return new InnerAwaitableImplement(_delayTime);        }        public class InnerAwaitableImplement:INotifyCompletion        {            private int _delayTime = 0;            private bool isFinished=false;            public InnerAwaitableImplement(int delayTime)            {                _delayTime = delayTime;            }            public bool IsCompleted            {                get                {                    return isFinished;                }            }            public void OnCompleted(Action continuation)            {                ThreadPool.QueueUserWorkItem(obj =>                 {                    Thread.Sleep(_delayTime);                    isFinished = true;                    continuation();                }, null);            }            public void GetResult()            {                            }        }    }    public static class IntExtend    {        public static TimeDelay.InnerAwaitableImplement GetAwaiter(this int delayTime)        {            TimeDelay td = new TimeDelay(delayTime);            return td.GetAwaiter();        }    }

Call this method as follows:

private async void button1_Click(object sender, EventArgs e)        {await 1000;            MessageBox.Show("OK");        }

Which of the following summarizes the usage of async and await?

We recommend that you check msdn.microsoft.com/en-us/library/hh191443 (v = vs.110). aspx and www.microsoft.com/..=19957.
 
C #50 what is async? What is the usage?

Declared functions are used asynchronously on the thread.
The await operator is applied to the task suspension method of An Asynchronous Method until the task is completed. Task indicates a job in progress.

..
Msdn.microsoft.com/..8.aspx

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.