Task.Faulted和Task.Exception

TaskStatus Enum或Task.Exception MSDN似乎都没有明确表示:

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

是的, Task.IsFaulted的文档明确指出:

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

参考源代码确实列出了几乎可以肯定的。 在FinishStageTwo我们看到内部FinishStageTwo仅在记录的exception时设置为出错:

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

因此,只有记录例外,国家才会出现问题。

Exception getter确实提到了可能的竞争条件:

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

如果IsFaultedException getter运行时变为true,则只会出现此竞争条件。

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

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

但是以下内容永远不会失败:

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

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