.Net6.0系列-2.Net 6及以上异步编程(一)

文章介绍了异步方法的使用,包括async关键字修饰的方法,返回值通常是Task,以及await的使用来获取异步操作的结果。强调了异步方法的“传染性”,即包含await的方法也需要声明为async。示例代码展示了如何避免使用.Wait()或.Result,以及线程池中异步委托的使用。文章还探讨了async方法的编译结果和线程切换机制,并指出接口中无法定义async方法。
摘要由CSDN通过智能技术生成

一.异步方法:用async关键字修饰的方法
1.异步方法的返回值一般是Task,T是返回类型,Task,异步方法以Async结尾.
2.异步方法没有返回值,最好声明为非泛型的Task
3.调用异步方法时加上await,即可获取返回T类型的值
4.异步方法的"传染性":一个方法中如果有await调用,则这个方法必须修饰为async
Example:

static async Task(或者void,尽量写Task) Main(string[] args)
{

string filename="E:\Temp\a.txt";
await File.WriteAllTextAsync(filename,"hello");
string s=await File.ReadAllTextAsync(filename);
}

二.异步方法编写

static async Task Main( [] args)
{
	int length=await DownloadHtmlAsync("http://www.baidu.com",@"e:\Temp\a\1.txt");
	Console.WriteLine(length);
}
//下面这种写法是不能使用await的时候的写法这种写法不好,还不如自己写多线程
//.Wait()/.Result不要用
static void Main(string[] args)
{
	Task<int> strLengthT=File.ReadAllTextAsync(@"e:\Temp\a\1.txt");
	int strLength=strLengthT.Result;
	Console.WriteLine(strLength);
	//不能写Async方法也没有返回值,
	//File.WriteAllTextAsync(@"e:\Temp\a\1.txt","aaaaaa").Wait();
}
static async Task<int> DownloadHtmlAsync(string url,string filename)
{
	string html="";
	using(HttpClient httpClient=new HttpClient)
	{
		html=await httpClient.GetStringAsync(url);
		await File.WriteAllTextAsync(filename,html);
	}
	return html.Length;
}

线程池中的异步委托使用:下面是lamda表达式:在lamda表达式前加async修饰就可以使用异步编程
static void Main(string[] args)
{
	ThreadPool.QueueUserWorkItem(async (obj)=>{
		while(true)
		{
			await File.WriteAllTextAsync(@"e:\Temp\a\1.txt","aaaaaaaa");
			Console.WriteLine("xxxxxx");
		}
	});
	Console.Read();
}

三 async与await解密
可用ILSpy反编译器反编译,该代码,可知async的方法会被C#编译器编译成一个类,根据await调用
进行切分为多个状态(swich(){case}),对async方法的调用会被拆分为对MoveNext的调用,await看似等待,经过编译
后,其实没有等待

static async Task Main(string[] args)
{
	using(HttpClient httpClient=new HttpClient())
	{
		string html=await httpClient.GetStringAsync("http://www.baidu.com");
		Console.WriteLine(html);
	}
	string txt ="hello cdc";
	string FileName="E:\temp\1.txt";
	await File.WriteAllTextAsync(FileName,txt);
	Console.WriteLine("写入成功!");
	string s =await File.ReadAllTextAsync(FileName);
	Console.WriteLine("文件内容:"+s);
}

四:async背后的线程切换
await调用的等待期间,.Net会把当前的线程返回会给线程池,等异步方法调用执行完毕之后,
框架会从线程池再取出一个线程来执行后续的代码,如果下面的代码sb很短,则不会切换线程,
在编写代码时应该尽量避免切换线程

static async Task Main(string[] args)
{
	Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
	StringBulider sb=new StringBulider();
	for(int i=0;i<10000;i++)
	{
		sb.Append("cdc");
	}
	await File.WriteAllTextAsync(@"E:\temp\1.txt",sb.ToString());
	Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
}

五.接口中的异步方法
async是提示编译器为异步方法中的await代码进行分段处理的,而一个异步方法是否修饰了async对于方法的调用者来讲是没有区别的,因为接口没有方法的实现,所以接口中的方法或者抽象方法不能修饰为async.
yield:用法也不能使用async修饰

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值