如何在 C# 中的策略断路器中同时等待多个任务?
How can I await multiple tasks at the same time inside policy circuit breaker in c#?
我找不到这个问题的答案。请帮忙。
场景
我可以使用 Task.WhenAll 一次等待多个任务。但我希望它在策略断路器 execution
方法中。下面是代码片段。我打了 2 次 API 并且想一次获得通话结果。在没有断路器的情况下,它可以正常工作,我可以稍后在我的代码中使用结果。但是我不明白如何在断路器内部使用 Task.WhenAll
调用 API。
var param1 = new Param
{
Category = Category.Manager,
FirstName = "John",
Address = "Sydney",
};
var param2 = new Param
{
Category = Category.Officer,
FirstName = "Adam",
Address = "Melbourne",
};
工作代码:
var results1 = Task.WhenAll(_apiClient.GetAsync(param1), _apiClient.GetAsync(param2));
//At this point results1 is NOT null and contains 2 items in it
问题:
var results2 = _policyCircuitBreaker.Execute(()=> Task.WhenAll(_apiClient.GetAsync(param1), _apiClient.GetAsync(param2)));
//at this point results2 is of type Task, how can I get the results2 similar to results1
您需要在 _policyCircuitBreaker
调用之外存储对任务的引用。
var param1Task = _apiClient.GetAsync(param1);
var param2Task = _apiClient.GetAsync(param2);
Task results = _policyCircuitBreaker.Execute(() => Task.WhenAll(param1Task, param2Task));
要么等待断路器调用,要么在完成时使用延续来获取结果。
等待示例:
await results;
var param1ApiResult = param1Task.Result;
var param2ApiResult = param2Task.Result;
继续示例(对于无法等待的代码路径)
results.ContinueWith(finishedTask =>
{
var param1ApiResult = param1Task.Result;
var param2ApiResult = param2Task.Result;
});
这两个示例都会为您提供结果 - 在 WhenAll
调用中执行它们之前,您只需要存储对每个任务的引用。这样一来,您就可以在 Tasks
完成后获得他们的结果。
我正在做一些假设,因为您的 post 不清楚您尝试使用的 API 以及执行方法 API 的样子。
一般来说,正如 Johnathon Sullinger 所说,如果你有一个 Task<TResult>
并且想以非阻塞方式获得 Task
的结果,await
-ing 那个Task<TResult>
(或使用延续)是要走的路。
但是假设您的断路器来自 Polly,原始问题的公式(在下面重复)不会给出您可能想要的异步断路器行为:
var results = _policyCircuitBreaker.Execute(() => Task.WhenAll(param1Task, param2Task));
该公式使用同步 .Execute(...)
:因此,通过 _policyCircuitBreaker
的 .Execute(...)
调用将仅控制 Task.WhenAll(...)
同步 ( near-immediately) 返回 Task<[]>
表示等待内部任务完成。断路器将 而不是 (在此公式中)管理您对 _apiClient.GetAsync(...)
.
的调用
假设您的意图是断路器应同时管理 _apiClient.GetAsync(param1)
和 _apiClient.GetAsync(param2)
调用(即响应这些调用可能引发的故障),您需要使用 Polly 的异步本机策略和 .ExecuteAsync()
重载:
var results3 = await _policyCircuitBreaker.ExecuteAsync(() => Task.WhenAll(_apiClient.GetAsync(param1), _apiClient.GetAsync(param2))));
.ExecuteAsync(...)
在内部等待您提供的委托,同时对其应用策略行为(在本例中为断路器行为)。
我找不到这个问题的答案。请帮忙。
场景
我可以使用 Task.WhenAll 一次等待多个任务。但我希望它在策略断路器 execution
方法中。下面是代码片段。我打了 2 次 API 并且想一次获得通话结果。在没有断路器的情况下,它可以正常工作,我可以稍后在我的代码中使用结果。但是我不明白如何在断路器内部使用 Task.WhenAll
调用 API。
var param1 = new Param
{
Category = Category.Manager,
FirstName = "John",
Address = "Sydney",
};
var param2 = new Param
{
Category = Category.Officer,
FirstName = "Adam",
Address = "Melbourne",
};
工作代码:
var results1 = Task.WhenAll(_apiClient.GetAsync(param1), _apiClient.GetAsync(param2));
//At this point results1 is NOT null and contains 2 items in it
问题:
var results2 = _policyCircuitBreaker.Execute(()=> Task.WhenAll(_apiClient.GetAsync(param1), _apiClient.GetAsync(param2)));
//at this point results2 is of type Task, how can I get the results2 similar to results1
您需要在 _policyCircuitBreaker
调用之外存储对任务的引用。
var param1Task = _apiClient.GetAsync(param1);
var param2Task = _apiClient.GetAsync(param2);
Task results = _policyCircuitBreaker.Execute(() => Task.WhenAll(param1Task, param2Task));
要么等待断路器调用,要么在完成时使用延续来获取结果。
等待示例:
await results;
var param1ApiResult = param1Task.Result;
var param2ApiResult = param2Task.Result;
继续示例(对于无法等待的代码路径)
results.ContinueWith(finishedTask =>
{
var param1ApiResult = param1Task.Result;
var param2ApiResult = param2Task.Result;
});
这两个示例都会为您提供结果 - 在 WhenAll
调用中执行它们之前,您只需要存储对每个任务的引用。这样一来,您就可以在 Tasks
完成后获得他们的结果。
我正在做一些假设,因为您的 post 不清楚您尝试使用的 API 以及执行方法 API 的样子。
一般来说,正如 Johnathon Sullinger 所说,如果你有一个 Task<TResult>
并且想以非阻塞方式获得 Task
的结果,await
-ing 那个Task<TResult>
(或使用延续)是要走的路。
但是假设您的断路器来自 Polly,原始问题的公式(在下面重复)不会给出您可能想要的异步断路器行为:
var results = _policyCircuitBreaker.Execute(() => Task.WhenAll(param1Task, param2Task));
该公式使用同步 .Execute(...)
:因此,通过 _policyCircuitBreaker
的 .Execute(...)
调用将仅控制 Task.WhenAll(...)
同步 ( near-immediately) 返回 Task<[]>
表示等待内部任务完成。断路器将 而不是 (在此公式中)管理您对 _apiClient.GetAsync(...)
.
假设您的意图是断路器应同时管理 _apiClient.GetAsync(param1)
和 _apiClient.GetAsync(param2)
调用(即响应这些调用可能引发的故障),您需要使用 Polly 的异步本机策略和 .ExecuteAsync()
重载:
var results3 = await _policyCircuitBreaker.ExecuteAsync(() => Task.WhenAll(_apiClient.GetAsync(param1), _apiClient.GetAsync(param2))));
.ExecuteAsync(...)
在内部等待您提供的委托,同时对其应用策略行为(在本例中为断路器行为)。