2017-01-27 35 views
0

在我的代码中,有几个策略需要保持一致。例如:用用户反馈撰写Polly政策

var myIOProblems = Policy 
    .Handle<IOException>() 
    .WaitAndRetryForever(i => TimeSpan.FromSeconds(2)); 

然后,我将有一些代码,会做的工作:

myIOProblems 
    .Execute(() => otherPath.CopyTo(otherPathPart.FullName)); 

这个伟大的工程,我能产仔后声明都在我的代码,改变行为一个中心的地方,这似乎都有效。

但是在某些地方,我需要向用户/框架提供一些有关问题正在发生的反馈。我可以写一个新的策略:

Policy 
    .Handle<IOException>() 
    .WaitAndRetryForever(i => TimeSpan.FromSeconds(2), (e, t, c) => 
    { 
     count++; 
     statusUpdate.PCall($"Copying {otherPath.Name}: {other.Name} -> {Name} (retry ({count}): {e.Message})"); 
    }) 
    .Execute(() => otherPath.CopyTo(otherPathPart.FullName)); 

但现在我已经失去了再利用的通用代码的能力。我真的想写的是类似于以下内容:

myIOProblems 
    .OnRetry(e => statusUpdate.PCall($"Error ({e.Message}), retrying")) 
    .Execute(() => otherPath.CopyTo(otherPathPart.FullName)); 

或类似的东西。我可能会忽视图书馆的某些东西,在这种情况下,我表示歉意!

+0

建议使用'执行()'重载服用上下文数据。您可以使用相同的通用策略,但将不同的上下文数据提供给不同调用位置的'Execute()'。 'onRetry'委托接收这个'Context'作为参数,并且可以相应地分配它的行为。 –

+0

上面的OnRetry是我编写的 - 展示我想要做的事情。但是,是的,在上下文中,这将被提供给WaitAndRetryForever,也许我可以在那里执行一个特殊的函子... – Gordon

+0

我指的是内置于所有Polly重试策略中的onRetry委托,而不是你编写了'.OnRetry()'。在你的第一个发布的代码示例中,代码'(e,t,c)=> {...}'是'onRetry'委托。你在那里的'c'输入参数是'Context'。这个参数'c'会传递你传递给Execute()'重载的上下文数据的任何上下文数据。因此,您可以使用相同的通用策略,但通过在不同的调用位置将不同的上下文数据传递给Execute()来改变'onRetry'行为。 –

回答

0

你可以用你的政策,在工厂类和getter函数将可选收到onRetry回调:

public class PolicyFactory 
{ 
    public static Policy GetMyPolicy(Action<Exception, TimeSpan, Context> onRetry = null) 
    { 
     return Policy 
      .Handle<IOException>() 
      .WaitAndRetryForever(i => TimeSpan.FromSeconds(2), onRetry); 
    } 
}