A Tour of Task, Part 4: Id
• CommentsId
I’ve talked a bit about task identifiers before, so I’ll just cover the high points here.
First, in spite of what the documentation says, the identifiers are not actually unique. They are pretty close, but not actually unique. The identifiers are generated on-demand, and will never be zero.
The task identifiers are useful if you’re reading the ETW events or debugging with the Tasks window, but they don’t really have a use case outside of diagnostics and debugging.
Sometimes developers try to use the task identifiers as keys in a collection, to associate “extra data” with a task. This is an incorrect approach; usually what they’re looking for is an async
local.
CurrentId
The CurrentId
property returns the identifier of the currently-executing task, or null
if no task is executing. The key word here is executing - CurrentId
only works for Delegate Tasks, not Promise Tasks.
In particular, the task returned by an async
method is a Promise Task; it logically represents the async
method, but it is not a Delegate Task, and does not actually have the asynchronous code as its delegate. CurrentId
may or may not be null
within an async
method, depending on the implementation details of the underlying SynchronizationContext
or TaskScheduler
.
For more information, including sample code, see my post on CurrentId
in async
methods.
In parallel code, it is possible to use the current task identifier as a key into a collection to store task-local values or results, but that is a poor approach IMO. It’s usually far better to use the PLINQ/Parallel
built-in local value and result aggregation support.