C#异步编程ConfigureAwait的使用

本文探讨了异步编程在GUI和服务器端应用的优势,重点讲解了async和await的关键作用,并提醒读者避免常见错误。通过实例解析了如何在UI线程正确使用await.ConfigureAwait,以及创建Task的不同方法。

异步编程是并发的一种形式,它有两大好处:

  • 对于面向终端用户的GUI程序,提高了响应能力
  • 对于服务器端应用,利用线程池实现了可扩展性

异步编程的两个关键字:asyncawait

需要注意:如果async方法有返回值,应返回Task<T>;如果没有返回值,应返回Task

严重警告:不要用void作为async方法的返回类型!async方法可以返回void,但这仅限于编写事件处理程序。一个普通的async方法如果没有返回值,要返回Task,而不是void

有了上述背景知识,我们来快速看一个例子:

async Task DoSomethingAsync()
{
	int val = 13; //以同步方式执行
	// 异步方式等待1秒
	await Task.Delay(TimeSpan.FromSeconds(1));
	val *= 2;
	// 异步方式等待1秒
	await Task.Delay(TimeSpan.FromSeconds(1));
	Trace.WriteLine(val);
}

上述代码,DoSomethingAsync方法在最开始时,以同步方式执行。当遇到await时,如果这个异步等待操作没有完成,就暂停DoSomethingAsync方法并返回这个Task,当这个Task完成操作后,继续以同步方式执行后续的代码。

问题:如果在UI线程中调用DoSomethingAsync,这个方法的每个同步程序块都将在此UI线程上运行。怎么避免这种错误行为呢?这就用到了await中的ConfigureAwait方法。

async Task DoSomethingAsync()
{
	int val = 13; //以同步方式执行
	// 异步方式等待1秒
	// 将continueOnCapturedContext参数设为false,则会在线程池线程里继续运行
	await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);
	val *= 2;
	// 异步方式等待1秒
	await Task.Delay(TimeSpan.FromSeconds(1));
	Trace.WriteLine(val);
}

关于异步方法,还有一条重要的准测:你一旦在代码中使用了异步,最好一直使用。调用异步方法时,应该用await等待它返回的task对象。一定要避免使用Task.WaitTask<T>.Result方法,因为它们会导致死锁

有两种基本的方法可以创建Task实例

  • Task.Run 创建计算类的任务(CPU实际执行的指令)
  • TaskFactory.StartNew 需要特定的计划运行
  • TaskCompletionSource<T> 创建基于事件的任务(例如:大部分I/O任务)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值