18:Polly-异步的委托执行

翻译自:https://github.com/App-vNext/Polly/wiki/Avoid-compiler-gotchas-mixing-sync-and-async-execution/_edit
点此跳转到系列目录

Asynchronous action execution

有关可用语法和策略的概述,请首先阅读自述文件:https://github.com/App-vNext/Polly#asynchronous-support。这篇文章详细描述了策略的异步操作.

Polly完全支持异步执行,使用异步方法:

  • RetryAsync
  • WaitAndRetryAsync
  • CircuitBreakerAsync
  • (etc)
  • ExecuteAsync
  • ExecuteAndCaptureAsync

取代他们对应的同步语法 Retry, WaitAndRetry 等.

策略实例是定义为同步或异步执行,但不能同时执行同步和异步。 您必须对同步定义的策略(如Retry)使用同步执行重载(如Execute); 对异步义的策略(如 RetryAsync)使用异步执行重载(如ExecuteAsync);

Async / await

在异步执行中, 所有的委托都是async ,执行都需要 await.

SynchronizationContext

作为提供异步API的库的推荐,默认情况下,异步延续(当方法从’ await '恢复时)不会在捕获的同步上下文上运行。

如果你需要整个.ExecuteAsync(…)调用在捕获的同步上下文中继续执行,请使用带bool continueOnCapturedContext的重载,并将其设置为true

Cancellation support

使用带有CancellationToken参数的 .ExecuteAsync(…)(或类似的)方法表示此异步任务可以取消。取消可能发生在如下情况:

  • 在委托尚未执行之前: 与Task.Run(…)和其他地方的基类库实现一样,如果在执行开始之前取消了取消令牌,则委托根本不会执行。
  • 在委托执行期间: 相关的.ExecuteAsync(…)重载所采取的操作委托具有CancellationToken 输入参数。CancellationToken传递给.ExecuteAsync(…)调用,并作为CancellationToken输入参数传递给被执行的委托,以支持在委托执行期间取消。
  • 在任何等待操作期间执行策略: 例如,重试之间的等待;等待舱壁执行槽。

所有取消都会照常抛出OperationCanceledException

Use async policies consistently for async execution

如果你错误地将一个同步策略与一个异步执行重载结合,如下所示(或反之亦然):

// Synchronous policy
var policy = Policy
    .Handle<Exception>()
    .Retry(3); // sync policy

// Asynchronous execute overload
var something = await policy.ExecuteAsync(async () => await DoSomethingAsync()); // async execute overload

那么Polly(直到v6)将抛出’ InvalidOperationException '。(从Polly v7开始,上面的示例将无法编译。)

使用Polly就像使用.Net中的其他异步代码一样,要注意同步和异步代码的混合.

避免混合执行同步和异步的编译器陷阱

(Avoid compiler gotchas mixing sync and async execution)

避免如下形式代码:

// 同步策略
var policy = Policy
    .Handle<Exception>()
    .Retry(3); 

// NB 不好的代码: 同步执行了异步的委托!
var something = await policy.Execute(async () => await DoSomethingAsync());

编译器将允许上述代码进行编译,因为async严格来说不是方法签名的一部分; 代码解析编译一个恰好返回Task<T>的委托。Polly还不能因为任何同步/异步不匹配而抛出或编译失败,因为策略(Retry)和执行重载(Execute)都匹配为同步。

注意 然而,Polly策略不会用这段代码来控制’ DoSomethingAsync() '的整个异步执行生命周期!

为什么它不工作?

当执行遇到第一个await语句时,所有.NET async方法都会同步返回一个表示正在执行的Task。 当一个异步委托,例如async () => await DoSomethingAsync()通过同步policy.Execute(...)运行时,策略只控制同步执行直到第一个await语句返回该’ Task '。

异步任务继续执行,并可能抛出错误,将错误放入返回的Task中。 然而,代码随后在策略执行外部等待任务(await policy.Execute(...)),因为同步策略执行已经成功完成同步返回Task。 因为上面的代码会在策略执行之外等待有错误的“任务”,所以异常会在没有策略控制的情况下被重新抛出。

翻译自:https://github.com/App-vNext/Polly/wiki/Avoid-compiler-gotchas-mixing-sync-and-async-execution/_edit
点此跳转到系列目录

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值