
186
|
第
14
章
14.4
隐式状态
问题
假设有一些状态变量,需要从调用栈的不同节点访问。比如,现在有一个用于记录日志的
当前操作标识符,但不希望把它作为参数添加到每个方法里。
解决方案
最佳方案是把参数添加到方法里,将数据作为类成员存储,或使用依赖项注入,从而为代
码的不同部分提供数据。但是在某些情况下,这样做会让代码过于复杂。
通过
AsyncLocal<T>
类型可以赋予状态一个对象,使之能出现在逻辑“上下文”中。下面
的代码展示了如何通过
AsyncLocal<T>
设置操作标识符,随后供日志记录方法读取:
private static
AsyncLocal<Guid> _operationId =
new
AsyncLocal<Guid>();
async
Task DoLongOperationAsync()
{
_operationId.Value = Guid.NewGuid();
await
DoSomeStepOfOperationAsync();
}
async
Task DoSomeStepOfOperationAsync()
{
await
Task.Delay(100); // 一些异步工作
// 此处是一些日志记录
Trace.WriteLine(
"
In operation:
"
+ _operationId.Value);
}
在很多情况下,较为复杂的数据结构(比如值栈)对于单个
AsyncLocal<T>
实例很有帮助。
但是需要注意,应该只在
AsyncLocal<T> ...