Task.Faulted and Task.Exception

空扰寡人 提交于 2019-12-23 08:33:33

问题


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

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


回答1:


Yes the documentation for Task.IsFaulted explicitly states that:

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

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 where 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.

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).

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.



来源:https://stackoverflow.com/questions/32273165/task-faulted-and-task-exception

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!