使用 Polly 运行 超时异步任务

Using Polly to run async task with timeout

我有一个简单的任务想 运行 在后台执行。该任务应该简单地尝试 移动 一个文件。此任务可能会失败,因为该文件正在另一个进程中使用。

我想在指定的时间段内重试此操作,然后 timeout 如果文件仍处于锁定状态。

我阅读了有关 Polly 的信息,并认为这将是满足我需求的理想选择。

该代码最终将包含在 ASP.NET 应用程序中,但我已经创建了一个小型 console 应用程序来尝试演示我正在努力实现的目标.

这是我第一次尝试使用 Polly,所以我在这里可能完全偏离了目标,但是一旦我 运行 Visual Studio 2013 中的应用程序,我就会收到以下错误:

An unhandled exception of type 'System.InvalidOperationException' occurred in mscorlib.dll

Additional information: Please use asynchronous-defined policies when calling asynchronous ExecuteAsync (and similar) methods.

代码如下:

class Program
    {
        static void Main(string[] args)
        {
            RunMyTask().GetAwaiter().GetResult();
        }

        private static async Task RunMyTask()
        {
            var timeoutPolicy = Policy.Timeout(TimeSpan.FromSeconds(20), TimeoutStrategy.Pessimistic, (context, span, arg3) => {});
            var policyResult = await timeoutPolicy.ExecuteAndCaptureAsync(async () =>
            {
                await Task.Run(() =>
                {
                    while (!MoveFiles())
                    {
                    }
                });
            });
            if (policyResult.Outcome == OutcomeType.Failure && policyResult.FinalException is TimeoutRejectedException)
            {
                Console.WriteLine("Operation Timed out");
            }
            else
            {
                Console.WriteLine("Operation succeeded!!!!!");
            }
        }

        private static bool MoveFiles()
        {
            try
            {
                var origFile = @"c:\temp\mydb.sqlite";
                var tempFile = @"c:\temp\mydb.sqlite.tmp";
                File.Move(origFile, tempFile);
                File.Move(tempFile, origFile);
                return true;
            }
            catch (Exception)
            {
                return false;
            }

        }

我做错了什么?

您需要使用 Timeoutasync 变体以及 async 执行方法。 Polly 有每个政策的 async 个变体,因此您需要一直 async

TimeoutPolicy timeoutPolicy = Policy
  .TimeoutAsync([int|TimeSpan|Func<TimeSpan> timeout]
                [, TimeoutStrategy.Optimistic|Pessimistic]
                [, Func<Context, TimeSpan, Task, Task> onTimeoutAsync])

From Timeout policy