如果配置等待设置为 False,则任务不会进入错误状态



这就是我要实现的目标。我启动了一个任务,不做等待/结果。为了确保如果启动的任务进入错误状态(例如,抛出异常),我通过在继续中调用环境 FailFast 来使进程崩溃。

我面临的问题是,如果我在代码中运行,则任务的状态(引发异常)将显示为"RanToCompletion"。我预计它是故障状态。

private Task KickOfTaskWorkAsync()
{
var createdTask = Task.Run(() => this.RunTestTaskAsync(CancellationToken.None).ConfigureAwait(false), CancellationToken.None);
createdTask.ContinueWith(
task => Console.WriteLine("Task State In Continue with => {0}", task.Status));
return createdTask;
}
private async Task RunTestTaskAsync(CancellationToken cancellationToken)
{
throw new Exception("CrashingRoutine: Crashing by Design");
}

这真是奇怪:(如果我删除 Task.Run 函数调用中的"ConfigureAwait(false)",任务确实会进入"继续"中的错误状态。 真的不知所措地解释发生了什么,并希望得到社区的一些帮助。

[更新]:我的同事指出了一个明显的错误。我在 Test.Run 中调用 RunTestAsync 时正在使用 ConfigureAwait,即使我不等待它。在这种情况下,ConfigureAwait 不会将任务返回到 Task.Run。如果我不调用 ConfigureAwait,任务确实会返回,并且事情会按预期工作。

你的错误是一个更广泛错误类别的具体例子:你没有观察到你真正关心Task

在代码示例中,RunTestTaskAsync()返回一个Task对象。它同步完成(因为没有await),因此当方法返回时,由于异常,它返回的Task对象已经出错。然后,您的代码在此出错的Task对象上调用ConfigureAwait()

但所有这些都发生在另一个Task,即你打电话时开始Task.Run()。此Task不会执行任何操作来观察异常,因此它会正常完成。

删除ConfigureAwait()调用时观察到异常的原因与调用本身无关。如果您离开呼叫并改为传递true,您仍然无法观察到异常。删除调用时可以观察到异常的原因是,如果没有对ConfigureAwait()的调用,lambda 表达式的返回值是一个Task,这会调用不同的Task.Run()重载。

此重载与其他重载略有不同。从文档中:

将指定的工作排入队列以在线程池上运行,并返回函数返回的任务的代理。

也就是说,当它仍然启动一个新的Task时,它返回的Task对象不代表那个Task,而是你的lambda表达式返回的对象。该代理的状态与它包装Task的状态相同,因此您可以看到它处于Faulted状态。

根据您发布的代码,我会说您首先不应该调用Task.Run()。以下内容也可以正常工作,没有代理的开销和复杂性:

static void Main(string[] args)
{
Task createdTask = RunTestTaskAsync();
createdTask.ConfigureAwait(false);
createdTask.ContinueWith(
task => Console.WriteLine("Task State In Continue with => {0}", task.Status)).Wait();
}
private static async Task RunTestTaskAsync()
{
throw new Exception("CrashingRoutine: Crashing by Design");
}

(我删除了CancellationToken值,因为它们与您的问题完全无关,在这里完全是多余的。

相关内容

  • 没有找到相关文章

最新更新