Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix ExecutionContext capture in Task (dotnet#17407)
When Task was refactored in core to remove the defunct StackCrawlMark support, the code that captured ExecutionContext was moved from a helper into TaskConstructorCore. In doing so, though, it was put at the beginning of TaskConstructorCore, even though in its previous location it would have come after the call to TaskConstructorCore. That change of place is causing an assert to fire, validating that m_stateFlags is still 0, which is failing because if ExecutionContext.Capture() returns null due to flow being suppressed, the code that stores the context sets a bit into m_stateFlags (to be able to differentiate null meaning no state flowed and null meaning default). The assert is correct, though, and a small bug did result from this: Task hasn't been entirely respecting ExecutionContext.SuppressFlow (which was added back in .NET Core 2.0), in that it won't flow the current context, but because it would overwrite that bit in m_stateFlags, it would treat a null ExecutionContext as default instead of as flow suppressed, and thus would use ExecutionContext.Default to invoke the Task's delegate. That in turn means that any EC changes made by the Task's delegate wouldn't be visible to the caller, as EC.Run would be used. The fix is simply to move the code to the end of TaskConstructorCore instead of having it at the beginning.
- Loading branch information