异步编程的学习
常见的三种异步编程
-
EAP
基于事件的异步程序。比如下载完成后事件的处理函数会执行,也就是说一个异步方法配一个执行事件,优点是简单,缺点是当实现复杂的业务的时候很麻烦。
private void button1_Click(object sender, EventArgs e) { //eap基于事件的异步编程 //EAP异步编程 当下面的代码下载完成后,并不是提交后完成的,而是在事件中处理提示完成的 //也就是EAP编程中一个异步方法配一个异步事件,当方法提交后,剩下的由事件来处理 WebClient wc = new WebClient(); wc.DownloadStringCompleted += wc_DownloadStringCompleted; wc.DownloadStringAsync(new Uri("http://www.xiaojun.fun")); }
2、APM
使用了APM的异步方法后会返回一个IAsyncResult的对象,这个对象有一个很重要的属性AsyncWaitHandle他是一个用来等待异步执行完成结束的一个同步信号。(Stream,SqlCommand,Socket都有)
private void button2_Click(object sender, EventArgs e) { //APM 使用Apm的异步方法后会返回一个IAsyncResult的对象 //这个对象有一个很重要的属性AsyncWaitHandle,他是一个用来等待异步执行完成的同步信号 FileStream fs = File.OpenRead("d:/1.txt"); byte[] buffer = new byte[1000000]; IAsyncResult result = fs.BeginRead(buffer, 0, buffer.Length, null, null);//开始 result.AsyncWaitHandle.WaitOne();//等待执行完成 fs.EndRead(result);//回收 textBox1.Text = Encoding.UTF8.GetString(buffer); }
3、TPL
TPL(Task Parallel Library)是.Net 4.0 之后带来的新特性,更简洁,更方便
TPL方法中如果有await(),则方法必须标记为async结尾的。
特点:方法都是以什么什么async结尾,返回的都是泛型Task<T>类型
Task: Task可以简单的理解为一个线程的封装,就相当于一个任务,程序提供一个任务给Task去执行,Task在执行的时候回马上返回主线程,当任务执行完成后就会告诉主线程,并继续执行Task后面的代码,异步执行。
/// <summary> /// 异步方法 tpl /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button3_Click(object sender, EventArgs e) { //TPL 基于任务的异步编程 简单的实现 FileStream fs = File.OpenRead("d:/1.txt"); byte[] buffer = new byte[1000000]; Task<int> t = fs.ReadAsync(buffer, 0, buffer.Length);//返回一个Task的泛型 t.Wait();//等待完成 textBox1.Text = Encoding.UTF8.GetString(buffer); }
自己手动编写异步方法
返回的值为Task<T>,一般命名规则是方法都是以Async结尾的
/// <summary> /// 自己编写异步方法 /// </summary> /// <returns></returns> static Task<string> TestAsync() { return Task.Run(() => "测试收到编写"); } /// <summary> /// 测试调用自己的异步方法 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private async void button5_Click(object sender, EventArgs e) { string result =await TestAsync();//异步获取返回值 MessageBox.Show(result); }