如何对 DotNetCircuitBreaker 进行异步调用

How to make async call to DotNetCircuitBreaker

我正在使用 DotNetCircuitBreaker 并尝试像这样调用异步方法

private async void button1_Click(object sender, EventArgs e)
{
  var circuitBreaker = new CircuitBreaker.Net.CircuitBreaker(
    TaskScheduler.Default,
    maxFailures: 3,
    invocationTimeout: TimeSpan.FromMilliseconds(100),
    circuitResetTimeout: TimeSpan.FromMilliseconds(10000));

  //This line gets the error... Definition looks like this
  //async Task<T> ExecuteAsync<T>(Func<Task<T>> func)      
  var result = await circuitBreaker.ExecuteAsync(Calc(4, 4));
}

private async Task<int> Calc(int a, int b)
{
  //Simulate external api that get stuck in some way and not throw a timeout exception
  Task<int> calc = Task<int>.Factory.StartNew(() =>
  {
    int s;
    s = a + b;
    Random gen = new Random();
    bool result = gen.Next(100) < 50 ? true : false;
    if (result) Thread.Sleep(5000);
    return s;
  });

  if (await Task.WhenAny(calc, Task.Delay(1000)) == calc)
  {
    return calc.Result;
  }
  else
  {
    throw new TimeoutException();
  }
}

参数 1:无法从 System.Threading.Tasks.Task"int" 转换为 System.Func"System.Threading.Tasks.Task"

如何修复我的计算方法与

看起来 CircuitBreaker.ExecuteAsync 需要类型为 Func<Task<T>> 的参数。您提供的是 Task<T>.

要修复它,您可以使用类似

的 lambda 表达式
var result = await circuitBreaker.ExecuteAsync(() => Calc(4, 4));

我同意德克的观点,因为您目前没有遵守预期的参数签名。另外,您是否考虑过研究 Polly library? It is quite mature and has a lot of functionality coming down the pike according to its roadmap 提供的断路器,包括一些匹配或超过 Netflix 的 Hystrix 断路器库 (java) 提供的功能的功能。