gpt4 book ai didi

c# - 当多个并行线程等待同一个 Task 实例然后抛出时会发生什么?

转载 作者:太空狗 更新时间:2023-10-29 23:12:41 26 4
gpt4 key购买 nike

通读answers to this question促使我思考当等待的任务抛出时异常情况下会发生什么。所有“客户”都可以观察到异常吗?我承认我可能在这里混淆了几件事;这就是我要求澄清的原因。

我将展示一个具体场景...假设我有一个服务器,其中包含由客户端启动的长期运行的 Task 实例的全局集合。在开始一个或多个任务后,客户端可以查询他们的进度并在结果可用时检索结果,以及可能发生的任何错误。

任务本身可能执行非常不同的特定于业务的事情 - 通常,没有两个是完全相同的。但是,如果其中一个客户端确实尝试启动与另一个客户端先前已启动的任务相同的任务,则服务器应该识别这一点并将第二个客户端“附加”到现有任务,而不是假脱机创建一个新副本。

现在,每次任何客户端查询它感兴趣的任务的状态时,它都会按照以下方式做一些事情:

var timeout = Task.Delay(numberOfSecondsUntilClientsPatienceRunsOut);
try
{
var result = await Task.WhenAny(timeout, task);
if (result == timeout)
{
// SNIP: No result is available yet. Just report the progress so far.
}

// SNIP: Report the result.
}
catch (Exception e)
{
// SNIP: Report the error.
}

简而言之,它为任务提供了一些合理的时间来完成它正在做的事情,然后回过头来报告正在进行的进度。这意味着存在一个潜在的重要时间窗口,多个客户端可以在该时间窗口中观察到同一任务失败。

我的问题是:如果任务恰好在此窗口期间抛出,是否所有客户端都观察到(并处理)了该异常?

最佳答案

Task.WhenAny 不会自行抛出。每the documentation :

The returned task will complete when any of the supplied tasks has completed. The returned task will always end in the RanToCompletion state with its Result set to the first task to complete. This is true even if the first task to complete ended in the Canceled or Faulted state.

您将返回 timeouttask

如果结果是 task,并且您等待它(或获取 Task.Result),并且 task 出错,那么它将扔。不管有多少调用者这样做,或者他们何时这样做——试图获得错误任务的结果总是会抛出错误。演示这一点的简单代码:

var t = Task.Run(() => throw new Exception(DateTime.Now.Ticks.ToString()));
try {
await t;
} catch (Exception e) {
Console.WriteLine(e.Message);
}
await Task.Delay(1000);
try {
await t;
} catch (Exception e) {
Console.WriteLine(e.Message);
}

这将打印相同的时间戳,两次。该任务只运行一次,并且只有一个结果,每次您尝试获取它时都会产生异常。如果您愿意,可以混合使用不同的线程或并行调用,这不会改变结果。

请注意,在超时的情况下,仍然存在竞争条件的基本可能性:两个不同的任务/线程,都在等待同一个任务,可能会在 await Task.WhenAny(timeout, task),基于他们观察到的第一个完成的任务。换句话说,即使 await Task.WhenAny(timeout, task) == timeouttask 仍然可以在 .WhenAny() 决定它已完成并最终将控制权归还给您。这是意料之中的,您的代码应该处理这个(在下一轮等待中,.WhenAny() 将立即返回错误任务)。

关于c# - 当多个并行线程等待同一个 Task 实例然后抛出时会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44760007/

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