异步编程是并发的一种形式,它有两大好处:
- 对于面向终端用户的gui程序,提高了响应能力
- 对于服务器端应用,利用线程池实现了可扩展性
异步编程的两个关键字:async和await。
需要注意:如果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.wait或task<t>.result方法,因为它们会导致死锁。
有两种基本的方法可以创建task实例:
task.run创建计算类的任务(cpu实际执行的指令)taskfactory.startnew需要特定的计划运行taskcompletionsource<t>创建基于事件的任务(例如:大部分i/o任务)
到此这篇关于c#异步编程configureawait的使用小结的文章就介绍到这了,更多相关c#异步configureawait内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论