大长不看版:
Task
的实例属性Id
在需要时才会分配值,不宜作为Task
的标识,这种情况应使用AsyncLocal
。Task
的静态属性CurrentId
表示当前正在运行的 Delegate Task 的Id
。
Id
int Id { get; }
我之前提过 task identifiers ,所以我这里只会介绍重点。
首先,无论文档是如何说的,Id
标识实际上并非唯一。它非常接近,但实际上并不唯一。标识在需要时生成,绝不会为0。
任务标识在你 读取ETW事件 或 使用任务窗格调试 时有用,但它们在诊断和调试之外没有任何用武之地。
有时开发者们会尝试使用任务标识作为集合的键,来为任务关联“额外数据”。这是个错误的方式,通常他们所要找的是 AsyncLocal
。
CurrentId
static int? CurrentId { get; }
CurrentId
属性返回当前在执行的任务的标识,或者在没有任务执行时返回 null
。这里的关键词是 执行 – CurrentId
只适用于 Delegate Tasks,不用于 Promise Tasks。
特别地,通过 async
方法(异步方法)返回的任务是 Promise Task,它逻辑上表示 async
方法,但它并非 Delegate Task,且实际上并没有异步代码作为它的委托。 在 async
方法内 CurrentId
可能是也可能不是 null
,依赖于底层 SynchronizationContext
或 TaskScheduler
的实现细节。
要看更多信息,包括示例代码,请看原作者的文章 async 方法中的 CurrentId
在并行代码中,可以使用当前任务标识作为键加入到集合中来存储任务本地值或结果,但在我看来那是个糟糕的方法。通常使用 PLINQ/Parallel 内置的本地值 和 结果聚合支持 要好得多。
原文链接:https://blog.stephencleary.com/2014/06/a-tour-of-task-part-4-id.html