如何在我的代码中正确实现 Polly 以避免卡顿

How to implement Polly correctly in my code to avoid freezing

我遇到了 Polly 导致线程冻结的问题。 正如您在 GetData() 方法下看到的那样将抛出异常。我想做的是在DoStuff()中的GetData()方法出现异常时继续Dostuff1和2;但似乎在用 polly 重试后,它只是卡住了,什么也没做...

我该如何解决这个问题?

private async Task StartUp()
{
        await DoStuff());
        // await next task DoStuff1();
        // await next task DoStuff2();
}


private async Task DoStuff()
{
        var data= await Task.WhenAll(Task.Run(() => GetData()));

        // Do stuff with the data
}


private async Task<Data> GetData()
{
     //read filepaths from file.

     var tasks = filePaths
             .Select(f => polly.MyPolicy().Execute(() => ReadDataFromCSV()))
             .ToArray();
    Return await tasks;
}

private Dictionary<string, DateTime?> ReadDataFromCSV()
{

     ///Throw exception....
}

    public PolicyForGetData()
    {
        return Policy
                 .Handle<Exception>()
                 .WaitAndRetry(
                    retryCount: 2,
                    sleepDurationProvider: t => TimeSpan.FromSeconds(5),
                    onRetry: (ex, t, i, c) => {
                        Console.WriteLine(ex.Message);
                    }
                 );
    }

我认为你误解了 Polly 的行为方式。假设 GetData() 总是抛出异常,那么您的应用程序将像这样工作

  1. GetData() 抛出
  2. Polly 第一次捕获重试
  3. GetData() 再次抛出
  4. Polly 第二次捕获重试
  5. GetData() 最后一次抛出。
  6. Polly 不会捕获或重试异常,因为您只要求它重试两次,异常会转义到 StartUp() 方法,从而阻止 DoStuff1()DoStuff2()从被调用。

例如。该程序的输出:

class Program
{
    static void Main(string[] args)
    {
        try
        {
            Policy
                 .Handle<Exception>()
                 .WaitAndRetry(
                    retryCount: 2,
                    sleepDurationProvider: t => TimeSpan.FromSeconds(5),
                    onRetry: (ex, t, i, c) => {
                        Console.WriteLine("OnRetry");
                    }
                 )
                 .Execute(() => ErrorMethod());

            Console.WriteLine("We never get here");
        }
        catch (Exception)
        {
            Console.WriteLine("Exception Handler");
        }
    }

    private static void ErrorMethod()
    {
        throw new InvalidOperationException("Badness");
    }
}

OnRetry
OnRetry
Exception Handler