gpt4 book ai didi

c# - Polly 后备中的动态委托(delegate)

转载 作者:行者123 更新时间:2023-12-02 20:30:11 25 4
gpt4 key购买 nike

我在 PolicyRegistry 中有以下政策可以在全局范围内重复使用:

var fallbackPolicy = Policy
.Handle<DrmException>().OrInner<DrmException>()
.Fallback(
fallbackAction: () => { //should commit or dispose the transaction here using a passed in Func or Action },
onFallback: (exception) => { Log.Error().Exception(exception).Message($"Exception occurred, message: {exception.Message}.").Write(); }
);

我有以下代码,我想在其中实现 fallbackPolicy:

   if(Settings.DRM_ENABLED)
drmManager.ExecuteAsync(new DeleteUser(123).Wait();//HTTP Call, throws DrmException if unsuccessful

//in some cases, there is an if(transaction == null) here (if transaction was passed as a parameter and needs to be committed here)
transaction.Commit();//if not thrown - commits the transaction

我希望它看起来像这样:

var fallbackPolicy = Policy
.Handle<DrmException>().OrInner<DrmException>()
.Fallback(
fallbackAction: (transaction) => { transaction.Dispose(); },
onFallback: (exception) => { Log.Error().Exception(exception).Message($"Exception occurred, message: {exception.Message}.").Write(); }
);

fallbackPolicy.Execute(() => drmManager.ExecuteAsync(new DeleteUser(123).Wait(), transaction)

据我所知,fallbackPolicy.Execute 需要执行 Action/Func,这要么成功,在这种情况下 fallbackPolicy 没有命中,要么失败,在这种情况下,fallbackPolicy 会启动一些预定义的 fallbackAction

我想做的是在执行时传入两个处理程序(处理事务的onFail(transaction)和提交事务的onSuccess(transaction))政策。有没有更简单的方法来代替包装它或使用 Polly 的上下文?

最佳答案

感觉这里有几个单独的问题:

  1. 如何使集中定义的 FallbackPolicy 执行动态操作?
  2. 如何让一个 FallbackPolicy 做两件事?
  3. 有了 Polly,我怎样才能在整体失败时做一件事,在整体成功时做另一件事?

我将分别回答这些问题,为您提供一个完整的工具包来构建您自己的解决方案 - 并为 future 的读者提供 - 但您可能不需要所有这三个工具来实现您的目标。如果您只想要一个解决方案,请切换到 3.

<强>1。如何让集中定义的 FallbackPolicy 做一些动态的事情?

对于集中定义的任何策略,是的,Context 是您可以为该执行传递特定内容的方式。引用文献:discussion in a Polly issue ; blog post .

你的部分问题似乎是让 FallbackPolicy 都记录;并处理交易。所以……

<强>2。如何让一个 FallbackPolicy 做两件事?

您可以传递一些动态的东西(如上)。另一种选择是使用两种不同的回退策略。你可以use the same kind of policy multiple times in a PolicyWrap .因此,您可以定义一个集中存储的 FallbackPolicy 来执行日志记录,并保持简单、非动态:

var loggingFallbackPolicy = Policy
.Handle<DrmException>().OrInner<DrmException>()
.Fallback(fallbackAction: () => { /* maybe nothing, maybe rethrow - see discussion below */ },
onFallback: (exception) => { /* logging; */ });

然后您可以在本地定义另一个 FallbackPolicy 以在失败时回滚事务。由于它是在本地定义的,因此您可能只是将 transaction 变量传递给它的 fallbackAction: 使用闭包(在这种情况下您不必使用 Context )。

注意:如果在 PolicyWrap 中使用两个 FallbackPolicy,您需要创建内部 FallbackPolicy 重新抛出(不是吞下)已处理的异常,以便外部 FallbackPolicy 也处理它。


回复:

What I would like to do is to pass in two handlers (onFail(transaction) which disposes the transaction and onSuccess(transaction) which commits the transaction)

没有任何政策对成功提供特殊处理,但是:

<强>3。有了 Polly,我怎样才能在整体失败时做一件事而在整体成功时做另一件事?

使用.ExecuteAndCapture(...) .这将返回具有属性 .Outcome == OutcomeType.SuccessfulOutcomeType.FailurePolicyResult(以及其他信息:参见 documentation)

总的来说,是这样的:

var logAndRethrowFallbackPolicy = Policy
.Handle<DrmException>().OrInner<DrmException>()
.Fallback(fallbackAction: (exception, context, token) => {
throw exception; // intentional rethrow so that the 'capture' of ExecuteAndCapture reacts. Use ExceptionDispatchInfo if you care about the original call stack.
},
onFallback: (exception, context) => { /* logging */ });

执行现场:

PolicyResult result = myPolicies.ExecuteAndCapture(() => ... ); // where myPolicies is some PolicyWrap with logAndRethrowFallbackPolicy outermost
if (result.Outcome == OutcomeType.Successful)
{ transaction.Commit(); }
else
{ transaction.Dispose(); }

关于c# - Polly 后备中的动态委托(delegate),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49018028/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com