的任务.Faulted和Task.Exception
本文关键字:Task Exception Faulted 任务 | 更新日期: 2023-09-27 18:10:11
TaskStatus Enum和Task均无。异常MSDN显示显式状态:
TasksStatus.Faulted
总是暗示Task.Exception != null
(和TaskStatus != Faulted
总是暗示Task.Exception == null
)?
是的,任务的文档。IsFaulted明确声明:
如果IsFaulted为true,则该任务的Status等于Faulted,且其Exception属性为非空。
参考源代码确实将其列为几乎肯定的。在FinishStageTwo
中,我们看到内部m_state
只有在记录异常时才被设置为faulted:
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 (i.e., if IsFaulted is set just after the check to IsFaulted above).
只有当Exception
getter正在运行时,IsFaulted
变为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);
如果您已经完成了等待任务完成,那么第一个case也永远不会失败。这可能就是为什么他们给它贴上"仁慈"的标签;然后把它留在里面。受此影响的代码量非常小。