c# - 我应该如何“等待”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;
}
}
}
}
解决方案
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);
推荐阅读
- sql - 从主表中获取所有信息,其中子表中的日期字段超过 365 天 - 只是稍微复杂一点
- javascript - 如何比较当前活动标签的 URL
- c# - AS400 锁定未使用的文件
- r - Markdown > html : 将表格标题居中
- css - Google amp-lightbox:内容高于屏幕,无法滚动到顶部
- java - Spring TestRestTemplate 解析错误而不是抛出 HttpClientErrorException
- yarnpkg - 纱线安装:EISDIR:对目录的非法操作,读取
- javascript - 根据数组中对象的索引,为数组中的每个对象分配一个新的键,并具有唯一的 id
- python - 有没有一种简单的方法将字符串变量一分为二?
- katalon-recorder - 使用不同定位器重播测试