C# 异步编程

一 异步编程

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(委托);
C# 异步编程_第1张图片

五 异步的流

与上面的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();
        }
    }
}

你可能感兴趣的:(C#程序设计,c#,ui,开发语言)