HTML5技术

C#异步的世界【上】 - 农码一生

字号+ 作者:H5之家 来源:H5之家 2017-01-18 13:00 我要评论( )

新进阶的程序员可能对async、await用得比较多,却对之前的异步了解甚少。本人就是此类,因此打算回顾学习下异步的进化史。 本文主要是回顾async异步模式之前的异步,下篇文章再来重点分析async异步模式。 APM APM 异步编程模型,Asynchronous Programming Mo

新进阶的程序员可能对async、await用得比较多,却对之前的异步了解甚少。本人就是此类,因此打算回顾学习下异步的进化史。 

本文主要是回顾async异步模式之前的异步,下篇文章再来重点分析async异步模式。

APM

APM 异步编程模型,Asynchronous Programming Model

早在C#1的时候就有了APM。虽然不是很熟悉,但是多少还是见过的。就是那些类是BeginXXX和EndXXX的方法,且BeginXXX返回值是IAsyncResult接口。

在正式写APM示例之前我们先给出一段同步代码:

button1_Click(object sender, EventArgs e) { Debug.WriteLine(+ Thread.CurrentThread.ManagedThreadId); request.GetResponse();//发送请求 Debug.WriteLine(+ Thread.CurrentThread.ManagedThreadId); label1.Text = ; }

【说明】为了更好的演示异步效果,这里我们使用winform程序来做示例。(因为winform始终都需要UI线程渲染界面,如果被UI线程占用则会出现“假死”状态)

【效果图】

看图得知:

  • 我们在执行方法的时候页面出现了“假死”,拖不动了。
  • 我们看到打印结果,方法调用前和调用后线程ID都是9(也就是同一个线程)
  • 下面我们再来演示对应的异步方法:(BeginGetResponse、EndGetResponse所谓的APM异步模型

    private void button2_Click(object sender, EventArgs e) { //1、APM 异步编程模型,Asynchronous Programming Model //C#1[基于IAsyncResult接口实现BeginXXX和EndXXX的方法] Debug.WriteLine(+ Thread.CurrentThread.ManagedThreadId); ); request.BeginGetResponse(new AsyncCallback(t =>//执行完成后的回调 { var response = request.EndGetResponse(t); (StreamReader reader = new StreamReader(stream)) { StringBuilder sb = new StringBuilder(); while (!reader.EndOfStream) { var content = reader.ReadLine(); sb.Append(content); } Debug.WriteLine(+ sb.ToString().Trim().Substring();//只取返回内容的前100个字符 Debug.WriteLine(+ Thread.CurrentThread.ManagedThreadId); label1.Invoke((Action)(() => { label1.Text = ; }));//这里跨线程访问UI需要做处理 } }), null); Debug.WriteLine(+ Thread.CurrentThread.ManagedThreadId); }

    【效果图】

     

    农码一生

    看图得知:

  • 启用异步方法并没有是UI界面卡死
  • 异步方法启动了另外一个ID为12的线程
  • 上面代码执行顺序:

    前面我们说过,APM的BebinXXX必须返回IAsyncResult接口。那么接下来我们分析IAsyncResult接口:

    首先我们看:

    确实返回的是IAsyncResult接口。那IAsyncResult到底长的什么样子?:

    并没有想象中的那么复杂嘛。我们是否可以尝试这实现这个接口,然后显示自己的异步方法呢?

    首先定一个类MyWebRequest,然后继承IAsyncResult:(下面是基本的伪代码实现)

    public class MyWebRequest : IAsyncResult { public object AsyncState { get { throw new NotImplementedException(); } } public WaitHandle AsyncWaitHandle { get { throw new NotImplementedException(); } } public bool CompletedSynchronously { get { throw new NotImplementedException(); } } public bool IsCompleted { get { throw new NotImplementedException(); } } }

    这样肯定是不能用的,起码也得有个存回调函数的属性吧,下面我们稍微改造下:

    然后我们可以自定义APM异步模型了:(成对的Begin、End)

    public IAsyncResult MyBeginXX(AsyncCallback callback) { var asyncResult = new MyWebRequest(callback, null); ); new Thread(() => //重新启用一个线程 { using (StreamReader sr = new StreamReader(request.GetResponse().GetResponseStream())) { var str = sr.ReadToEnd(); asyncResult.SetComplete(str);//设置异步结果 } }).Start(); return asyncResult;//返回一个IAsyncResult } public string MyEndXX(IAsyncResult asyncResult) { MyWebRequest result = asyncResult as MyWebRequest; return result.Result; }

    调用如下:

     

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    相关文章
    • 那些年搞不懂的术语、概念:协变、逆变、不变体 - 农码一生

      那些年搞不懂的术语、概念:协变、逆变、不变体 - 农码一生

      2016-08-30 17:00

    • 用canvas画简单的“我的世界”人物头像 - 玉菲莎

      用canvas画简单的“我的世界”人物头像 - 玉菲莎

      2016-07-27 14:00

    • JS运动从入门到兴奋1 - 沫晴的前端世界

      JS运动从入门到兴奋1 - 沫晴的前端世界

      2016-07-16 11:00

    • 过目不忘JS正则表达式 - 沫晴的前端世界

      过目不忘JS正则表达式 - 沫晴的前端世界

      2016-07-14 14:00

    网友点评