自己实现async和await
2018-06-17 19:55:50来源:未知 阅读 ()
无意当中看了一些博文,说有人想自己尝试实现基于异步操作的方法:
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"); }
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- PHP简单实现单点登录功能示例 2019-10-09
- thinkphp5框架前后端分离项目实现分页功能的方法分析 2019-10-08
- PHP7 安装event扩展的实现方法 2019-10-08
- php实现的数组转xml案例分析 2019-09-30
- PHP 使用 Swoole - TaskWorker 实现异步操作 Mysql 2019-09-23
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash