一 异步编程
1 异步 asynchronize
2 主要解决的事情是
① 等待一些耗时的任务(特别是文件,网络操作)而不阻塞当前任务;
② 异步编程提高响应能力(特别是UI)
开始一个任务后,让任务在离感应线程中执行,本线程可以继续执行别的事情,然后等待那个任务执行完毕。
二 传统的方法1
1 使用委托BeginInvoke及EndInvoke
2 如下:
① PrintDelegate printDelegate=Print;
② IAsncResult result=printDelegate.BeginInvoke(“Hello World”,null,null);
③ Console.WriteLine(“主线程继续执行”);
④ 当使用BeginInvoke异步调用方法时,如果方法未执行完,EndInvoke方法就会一直阻塞,直到被调用的方法执行完毕;
⑤ int n=printDelegate.EndInvoke(result);
三 传统的方法2
1 使用回调
如:
① Console.WriteLine(“主线程”);
② PrintDelegate printDelegate=Print;
③ printDelegate.BeginInvoke(“Hello World.”,PrintComeplete,printDelegate);
④ Console.WriteLine("主线程继续执行…);
⑤ 回调方法要求 返回类型为void 只有一个参数IAsyncResult
public static void PrintCompelete(IAsyncResult result)
{
(result.AsyncState as PrintDelegate).EndInvoke(result);
Console.WriteLine(“当前线程结束。”+result.AsyncState.ToString());
}
四 C# 5.0的新方法
C# 5.0(.Net framework4.5 Visula Studio 2013)
新增await及async两个关键词
await表示等待任务的执行
async修饰一个方法,表示其中有await语句;
1 一般的写法
Task<double>FacAsync(int n)
{
return Task<doouble>.Run(()=>//Task表示要执行任务
{
double s=1;
for(int i=1;i<n;i++)
s=s*i;
return s;
});
}
async void Test()
{
double result=await FacAsync(10);//调用异步方法
Console.WriteLine(result);//异步方法执行完后才执行此句
}
double result=await FacAsync(10);//此处会开心线程处理然后方法马上返回
//这之后的所有代码都会被封装成委托,在任务完成时调用
Console.WriteLine(result);
它解决了传统方法中“异步任务与回调方法分开写”的问题
相当于
System.Runtime.CompilerServices.TaskAwaiter<double>awaiter
=FacAsync(10).GetAwaiter();
awaiter.OnCompleted(()=>
{
double result=awaiter.GetResult();
Console.WriteLine(result);
});
在WinForm中 当异常执行完成后,使用解码线程来执行回调,所以写起来更简洁
async Task<string>AccessTheWebAsync(string url)
{
HttpClient client=new HttpClient();
Task<string>task=client.GetStringAsync(url);//异步
DoIndependentWork();//做其他事
string urlContents=await task;//等待异步执行完毕
return urlContents;
}
async private void button1_Click(object sender,EventArgs e)
{
string content=await AccessTheWebAsync(url);
this.textBox2.Text=content;//编译器让这句在界面线程上执行
}
await后面的语句,就不用麻烦写成Invoke(委托);
五 异步的流
与上面的HttpClient相似,Stream等类也提供了异步方法
如
await myStream.WriteAsync(…);
这比传统的BeginWrite()+回调函数+EndWrite()要方便很多;
也可以这样:
Task task=myStream.WriteAsync();//异步
DoIndependentWork();//做其他事
await task;//等待异步执行完毕
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Linq;
using System.IO;
using System.Threading;
using System.Data;
using System.Drawing;
namespace 使用Stream的异步方法
{
internal class AsyncStream
{
async Task<int>WriteFile()
{
using (StreamWriter sw = new StreamWriter(
new FileStream("aaa.txt", FileMode.Create)))
{
await sw.WriteAsync("my text");
return 1;
}
}
async static void Test()
{
AsyncStream a =new AsyncStream();
await a.WriteFile();
Console.WriteLine("Write OK");
}
static void Main(string[] args)
{
Test();
Console.ReadKey();
}
}
}