Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 任务不存在';如果ConfigurAwait设置为False,则不会进入故障状态_C#_Asynchronous_Parallel Processing_Task_Configureawait - Fatal编程技术网

C# 任务不存在';如果ConfigurAwait设置为False,则不会进入故障状态

C# 任务不存在';如果ConfigurAwait设置为False,则不会进入故障状态,c#,asynchronous,parallel-processing,task,configureawait,C#,Asynchronous,Parallel Processing,Task,Configureawait,这就是我想要实现的目标。我启动了一项任务,但不等待它的结果。为了确保如果启动的任务进入故障状态(例如,抛出异常),我在Continuation中调用Environment FailFast使进程崩溃 我所面临的问题是,如果我在ContinueWith中运行下面的代码,任务的状态(引发异常)将显示为“RanToCompletion”。我以为这是一个错误的状态 private Task KickOfTaskWorkAsync() { var createdTask =

这就是我想要实现的目标。我启动了一项任务,但不等待它的结果。为了确保如果启动的任务进入故障状态(例如,抛出异常),我在Continuation中调用Environment FailFast使进程崩溃

我所面临的问题是,如果我在ContinueWith中运行下面的代码,任务的状态(引发异常)将显示为“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)',任务在Continue with中确实会进入错误状态。我真的无法解释发生了什么,希望社区能提供一些帮助


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

您的错误就是一个特定的b类错误示例roader错误类别:你没有观察到你真正关心的
任务

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

但所有这些都发生在另一个
任务中,即在调用
Task.Run()
时启动的任务。此
任务
不会观察异常,因此它正常完成

删除
ConfigureAwait()时观察异常的原因
调用与调用本身无关。如果您离开调用并传递了
true
,您仍然无法观察到异常。删除调用时可以观察到异常的原因是,没有调用
configurewait()
,lambda表达式的返回值是一个
任务
,此函数调用

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

对要在线程池上运行的指定工作进行排队,并为函数返回的任务返回代理

也就是说,虽然它仍然启动一个新的
任务
,但它返回的
任务
对象并不代表该
任务
,而是由lambda表达式返回的对象。该代理与它包装的
任务
具有相同的状态,因此您可以在
故障
状态中看到它

根据您发布的代码,我认为您首先不应该调用
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
值,因为它们与您的问题毫无关系,在这里是完全多余的。)

您使用
ContinueWith
有什么原因吗?
ContinueWith
是针对异步等待前的时代;现在您可以使用
await RunTestTaskAsync()
后接
Console.WriteLine()
并以更标准的方式捕获您想要的任何异常;即
尝试
catch
@sellotape:现在
wait
是一种更惯用的处理连续性的方法,这是正确的。但是,OP即使使用
wait
,也会有同样的问题。他们将等待错误的
任务ect并仍会看到任务处于非故障状态。@PeterDuniho-如果他要等待
createdTask
,那么是的,但如果他只是等待
RunTestTaskAsync()
(这似乎没有什么理由不这样做,但我想没有足够的上下文来确定),
catch
将捕获他抛出的异常。@sellotape:“如果他只是等待RunTestTaskAsync()”——但他不是。他不是。这是他问题的全部症结所在。我的观点是,仅仅告诉他使用
await
根本不能解决他的问题。如果
ContinueWith()
被替换为
wait
在这里,同样的问题仍然会发生。问题只是稍微改写了代码。@PeterDuniho-我不是说这是一个答案;而只是OP可能会发现有用的相关信息,这就是为什么我发表了评论,而不是答案(你的答案涵盖了问题)。我在第一条评论中也特别提到了
await runtesttaskaync()
。在没有相应的
await
的情况下配置
await
(即
createdTask.ConfigureAwait(false)
)有什么意义?更仔细地看,代码似乎从未运行过(在此之前会引发异常).@ta.speot.is:对
configurewait()
的调用会影响延续,无论是通过
ContinueWith()完成的
wait
语句。对于异常,您也弄错了。线程中没有观察到异常,因为它是由方法返回的
任务
封装的。如果您费心运行代码,您会知道的。有趣的是,人们投票时没有真正理解他们在看什么。RE:#1我在下面impression
ConfigureAwait
返回一个
ConfiguredTaskAwaitable
,这就是保存配置的东西。你是对的re:#2.@ta.speot.is:是的,它是正确的。你必须通过一个调度程序来继续()。等待被丢弃,没有任何效果。不过,问题的关键是答案是正确的,代码的编写只是为了尽可能接近原始问题的代码,同时提供符合OP期望的行为。几乎不值得向下投票,因为原始代码是我