gpt4 book ai didi

c# - 如何在 C# 中实现一种机制,仅当前一个任务未在特定时间内完成时才启动任务?

转载 作者:行者123 更新时间:2023-12-05 03:27:52 26 4
gpt4 key购买 nike

我有一个用例,其中我的服务与具有多个后备服务器的服务器通信。我正在尝试开发一种机制,在该机制中,我首先与主服务器通信,但它在 x 秒内没有响应,我尝试另一个后备服务器,依此类推,直到其中任何一个响应。

通过调查,我发现我可以使用 Timer()LinkedCancellationToken,但它们都不适合我的用例。

Timer() 会为以后安排一些事情,但我只想在主服务器未在限制内响应时安排它。

LinkedCancellationToken 如果任何链接的 cancellationToken 被取消,我可以取消调用,但这不是我的用例。

关于如何实现这个的任何想法?

最佳答案

原则上,这非常简单:您可以await Task.WhenAny(...),传入您创建的任务以及另一个将在您创建时结束的“延迟”任务厌倦了等待并准备尝试另一台服务器。

当然,最佳实践表明您永远不应让任何任务处于未等待状态,并且您应该在收到好的请求后取消其他请求。这会使事情变得有点复杂:

async Task<Response> GetFirstServerResponse(IEnumerable<string> serverNames, CancellationToken cancellationToken)
{
var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
var tasks = new List<Task<Response>>();
try
{
foreach (var serverName in serverNames)
{
tasks.Add(TalkToServer(serverName, linkedTokenSource.Token));
await Task.WhenAny(tasks.Append(Task.Delay(delay)));
var completedTask = tasks.FirstOrDefault(t => t.IsCompleted);
if(completedTask != null)
{
return await completedTask;
}
}
var firstCompleted = await Task.WhenAny(tasks);
return await firstCompleted;
}
finally
{
// Make all the incomplete tasks stop trying.
linkedTokenSource.Cancel();
try
{
// Never leave tasks unawaited.
// Since we cancelled these, they should all finish very quickly now.
await Task.WhenAll(tasks);
}
catch (OperationCanceledException) // ignore tasks that got cancelled.
{
}
}
}

this dotnetfiddle 中试用它.

根据您的要求,您可能需要对此进行调整。例如,我假设如果请求以错误结束,那么您想要保释并暴露该错误。如果您预计某些类型的间歇性错误可能发生在一台服务器上而不是其他服务器上,并且您希望在任何请求成功时忽略错误,则需要对此代码进行一些更改。

关于c# - 如何在 C# 中实现一种机制,仅当前一个任务未在特定时间内完成时才启动任务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71344474/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com