Task.Faulted 和 Task.Exception [英] Task.Faulted and Task.Exception

查看:31
本文介绍了Task.Faulted 和 Task.Exception的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

TaskStatus枚举Task.Exception MSDN 似乎明确指出:

Neither TaskStatus Enum or Task.Exception MSDN appear to state explicity:

TasksStatus.Faulted 是否总是暗示 Task.Exception != null(并且 TaskStatus != Faulted 总是暗示 Task.Exception== null)?

Does TasksStatus.Faulted ALWAYS imply Task.Exception != null (and TaskStatus != Faulted always imply Task.Exception == null)?

推荐答案

是的,Task.IsFaulted 明确指出:

如果 IsFaulted 为 true,则任务的 Status 等于 Faulted,并且其 Exception 属性将为非空.

If IsFaulted is true, the task's Status is equal to Faulted, and its Exception property will be non-null.

参考源代码确实将其列为几乎可以肯定的.在 FinishStageTwo 中,我们看到内部 m_state 仅在记录异常时才设置为 faulted:

The reference source code does list the as an almost certainly. In FinishStageTwo, we see that the internal m_state is only set to faulted if exceptions were recorded:

  if (ExceptionRecorded)
  {
      completionState = TASK_STATE_FAULTED;
      ...
  }
  ...
  Interlocked.Exchange(ref m_stateFlags, m_stateFlags | completionState);

所以只有在记录异常时状态才会出错.

So the state will only be faulted if exceptions were recorded.

然而,Exception getter 确实提到了一个可能的竞争条件:

However, Exception getter does mention a possible race condition:

// Only return an exception in faulted state (skip manufactured exceptions)
// A "benevolent" race condition makes it possible to return null when IsFaulted is
// true (i.e., if IsFaulted is set just after the check to IsFaulted above).

只有当 IsFaultedException getter 正在运行时变为 true 时,才会发生这种竞争条件.

This race condition will only occur if IsFaulted becomes true as Exception getter is running.

因此,如果在任务执行时调用以下代码可能会失败:

So the following code could fail if called while the task is executing:

 var ex = task.Exception;
 var faulted = task.IsFaulted;
 if (faulted)
     Assert.IsTrue(ex != null);

但是以下永远不会失败:

However the following will never fail:

 var faulted = task.IsFaulted;
 var ex = task.Exception;
 if (faulted)
     Assert.IsTrue(ex != null);

如果您已经完成等待任务完成,第一种情况也永远不会失败.这可能就是为什么他们将其标记为仁慈"的原因.并保留它.受它影响的代码量非常小.

The first case will also never fail if you've already finished waiting for the task to complete. That's probably why they labeled it as "benevolent" and left it in. The amount of code that would be affected by it is pretty small.

这篇关于Task.Faulted 和 Task.Exception的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆