c# 异步编程

20191123

今天学了一些关于异步编程的知识点,现总结记录以下关键点:

1、报告进度

在异步操作过程,展示操作的进度

使用IProgress<T>和Progress<T>。在async方法里传入IProgress<T>,其中T是需要报告的进度类型。

注意:由于IProgress<T>.Report方法是可以移步的,意味着报告进度之前,异步方法会继续运行,因此最好将T定义为一个不可变类型(至少是值类型,引用类型的话需要在调用IProgress<T>.Report时创建一个单独副本)

 

2 、Task.WhenAll

输入多个任务,完成后返回一个完成的Task对象,异常时会放在返回的Task里,多个异常也会如此。但在await调用时,只抛出一个异常。

 

3、任务完成时的处理

A

var processingTasks = (from t in tasks    select AwaitAsync(t).toArray())

await Task.WhenAll(processingTasks);

B

扩展方法:OrderByCompletion

foreach (var task in tasks.OrderByCompletion())
{
    var resulr = await task;
    Trace.WriteLine(result);
}

 

4、避免线程上下文延续

async方法在被await调用后恢复运行时,会在原上下文中运行,如果是UI上下文,可能会有大量的async方法需要在UI上下文中恢复。

为避免在上下文中恢复,可以通过await调用ConfigureAwait()方法的返回值,将参数continueOnCaptureContext=false,  

使代码一开始在调用的线程里执行,当被await暂停后,转到线程池线程里运行

大部分I/O型任务采用 TaskCompletionSource.

UI线程中有多少延续任务算多,winRT团队的指导标准,100个/s。

推荐:核心库一直使用ConfigureAwait,在外围用户界面中,只在需要时恢复上下文。

如果一部分需要使用,一部分不需要,建议拆分成多个async方法。

 

5、async异常

async Task方法引发的异常,存放在返回的Task中,只有当Task对象被await调用时,才会抛出(重新抛出)

await重新抛出的异常,原始的栈轨迹会被正确保存。返回的Task可能会有多个异常,但await智慧抛出一个。需要获取多个异常,需要根据Task的exception属性进行判断。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值