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
)?
Yes, the documentation for Task.IsFaulted explicitly states that:
If IsFaulted is true, the task's Status is 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 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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With