gpt4 book ai didi

c# - 结束任务以防止失控的最佳方式是什么

转载 作者:行者123 更新时间:2023-11-30 16:53:01 25 4
gpt4 key购买 nike

我创建了下面的函数,它会等待所有任务完成或在发生取消或超时时引发异常。

public static async Task WhenAll(
IEnumerable<Task> tasks,
CancellationToken cancellationToken,
int millisecondsTimeOut)
{
Task timeoutTask = Task.Delay(millisecondsTimeOut, cancellationToken);
Task completedTask = await Task.WhenAny(
Task.WhenAll(tasks),
timeoutTask
);
if (completedTask == timeoutTask)
{
throw new TimeoutException();
}
}

如果所有 tasks 在长时间超时(即 millisecondsTimeOut = 60,000)之前完成,timeoutTask 会一直停留到 60 秒即使在函数返回后也已经过去了?如果是,解决失控问题的最佳方法是什么?

最佳答案

是的,timeoutTask 会一直挂起直到超时结束(或者 CancellationToken 被取消)。

您可以通过传入一个不同的 CancellationToken 来修复它,您可以使用 CancellationTokenSource.CreateLinkedTokenSource 创建一个新的 CancellationTokenSource 并在结尾。您还应该等待完成的任务,否则您并没有真正观察到异常(或取消):

public static async Task WhenAll(
IEnumerable<Task> tasks,
CancellationToken cancellationToken,
int millisecondsTimeOut)
{
var cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
var timeoutTask = Task.Delay(millisecondsTimeOut, cancellationTokenSource.Token);
var completedTask = await Task.WhenAny(Task.WhenAll(tasks), timeoutTask);
if (completedTask == timeoutTask)
{
throw new TimeoutException();
}

cancellationTokenSource.Cancel();
await completedTask;
}

但是,如果您不需要区分 TimeoutExceptionTaskCancelledException,我认为有一种更简单的方法可以实现您想要的。您只需添加一个在 CancellationToken 被取消或超时结束时被取消的延续:

public static Task WhenAll(
IEnumerable<Task> tasks,
CancellationToken cancellationToken,
int millisecondsTimeOut)
{
var cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
cancellationTokenSource.CancelAfter(millisecondsTimeOut);

return Task.WhenAll(tasks).ContinueWith(
_ => _.GetAwaiter().GetResult(),
cancellationTokenSource.Token,
TaskContinuationOptions.ExecuteSynchronously,
TaskScheduler.Default);
}

关于c# - 结束任务以防止失控的最佳方式是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31885498/

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