首页 > 解决方案 > 我应该如何“等待”C# Polly 策略列表?

问题描述

我正在使用 Polly 库来监视/重新启动 C# 中的任务。我有一些“愚蠢”的示例代码来测试重启机制。

我注意到我的 'await Task.WhenAll(policy_list.ToArray());' 并不总是一直等待政策。相反,这只是立即通过。

什么是“无限”等待的正确方法,这样 Polly 会一直监控我的任务?

using System;
using System.IO;
using System.Collections.Generic;
using Polly;
using System.Threading.Tasks;

namespace Sampler
{
    class Program
    {
        public static async Task Main(string[] args)
        {

            // create and execute policies for each sampler
            List<Task> policy_list = new List<Task>();
            for(int i = 0; i < 2; i++)
            {
                var policy = Policy
                    .Handle<Exception>()
                    .RetryForeverAsync()
                    .ExecuteAsync(async () => await Program.TaskMethod(i.ToString()));

                policy_list.Add(policy);
            }

            await Task.WhenAll(policy_list.ToArray());

            Console.WriteLine("Press any key to exit...");
            Console.ReadLine();
        }

        public static async Task TaskMethod(string task_id)
        {
            Console.WriteLine("Starting Task {0}", task_id);
            while (true)
            {
                await Task.Delay(5000);
                Console.WriteLine("Hello from task {0}", task_id);

                int i = 0;
                int b = 32 / i;

            }
        }
    }
}

标签: c#async-awaittaskpolly

解决方案


public async Task AwaitAndProcessAsync<T>(Task<T> task) where T : PolicyResult<ExecutionResult>
{
    var result = await task;
    if (result.Outcome == OutcomeType.Failure)
    {
        var android = result.Context.Values.OfType<AndroidTestHelper>().First();
        if (result.FinalException != null)
        {
            LogsHelper.iLog.Fatal($"{result.Context.First().Key} failed after too many retries!");
        }
    }
}

//where ExecutionResult : enum {PASSED, FAILED}

使用此功能,您可以在并行执行中返回一些值后等待和处理每个任务,如果Task.WhenAll仅使用您将能够在完成所有任务后记录结果!

var list = await GenerateSomeDevices(20);
var tasks = new List<Task<PolicyResult<ExecutionResult>>>();

foreach (var device in list)
{
    var android = new AndroidTestHelper(device);

    var t = bulkHeadPolicy.ExecuteAndCaptureAsync(async (context, _token) =>
    {
        LogsHelper.iLog.Debug($"[{device.Index}] start testing..");
        return await android.TestDriver(_token);
    }, new Dictionary<string, object>() { { $"[{device.Index}] Process", android } }, cancellationToken);

    tasks.Add(t);
    await Task.Delay(10000);
}

var processingTasks = tasks.Select(AwaitAndProcessAsync).ToList();

await Task.WhenAll(processingTasks).ContinueWith((task) =>
{
    if (task.IsCompleted)
        LogsHelper.iLog.Information("DONE");
}, cancelationToken);

推荐阅读