国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

自己實現async和await

2019-11-14 16:29:46
字體:
來源:轉載
供稿:網友

  無意當中看了一些博文,說有人想自己嘗試實現基于異步操作的方法:

  1)直接使用Task(不說咯,這個是微軟給我們的標準實現方法)。

  2)必須繼承INotifyCompletion接口,同時自己實現IsCompleted(必須)和Result(可選),GetResult(必須)OnCompleted(必須)方法:

  下面是一個具體的例子(自實現異步函數): 

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;            }        }    }

GetResult和Result屬性應該實現同步的方法(阻塞線程的),OnCompleted實現異步方法(必須新線程去處理)。這樣的話,一旦主程序這樣調用:

AwaitableFunc<int> afunc = new AwaitableFunc<int>(() =>            {                //模擬一個長時間的任務,注意這里如果用同步機器就死掉                Thread.Sleep(5000);                return 1;            });            var result =  afunc.GetAwaiter();            result.OnCompleted(() =>            {                MessageBox.Show(result.GetResult().ToString());            });

你會發現,GetAwaiter方法會先被執行,判斷IsCompleted是否為false,如果是false,先執行OnCompleted的方法(作為回調函數一樣的性質)先保留,然后開辟新線程執行GetResult(),最后回調到OnCompleted執行回調函數。

你也可以這樣調用:

private  async void button1_Click(object sender, EventArgs e)        {            AwaitableFunc<int> afunc = new AwaitableFunc<int>(() =>            {                //模擬一個長時間的任務,注意這里如果用同步機器就死掉                Thread.Sleep(5000);                return 1;            });            var result = await afunc;            MessageBox.Show(result.ToString());        }

類似于第一個示例(這里就指出了await其實本質是一個回調函數,編譯器自動把await下面的東西全部包含到里邊去了,簡單敘述原理,注意代碼中紅色標示部分的位置!)。

其實,GetResult并不是一定需要的,比如這個對int任意進行延時(不直接調用Task.Delay方法,自己寫一個唄):

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()            {                            }        }    }

這樣使用:

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

更簡單地——擴展方法:

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();        }    }

這樣調用:

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 巴楚县| 佛山市| 海阳市| 馆陶县| 康马县| 临沭县| 渭源县| 大安市| 仙居县| 深泽县| 齐齐哈尔市| 邛崃市| 宁阳县| 育儿| 葵青区| 鄱阳县| 阿拉善盟| 呼和浩特市| 三原县| 开封县| 盐池县| 林口县| 和平县| 册亨县| 涞源县| 嘉荫县| 池州市| 新蔡县| 江孜县| 临高县| 广安市| 青神县| 桃江县| 龙胜| 焦作市| 文水县| 金湖县| 驻马店市| 翼城县| 明光市| 丹江口市|