我有一个UserScope
类,其功能与TransactionScope
类似,即它将当前状态存储在本地线程中。对于await
的调用,这当然不起作用,在.NET 4.5.1中添加TransactionScope
之前,TransactionScopeAsyncFlowOption
也没有。
我可以使用什么替代线程本地,以便UserScope
可以在单线程和多线程场景中使用相同的? (如果我安装了4.5.1,我会反编译以查看TransactionScope
是如何做到的。)这是我所拥有的简化版本:
class User {
readonly string name;
public User(string name) {
this.name = name;
}
public string Name {
get { return this.name; }
}
}
class UserScope : IDisposable {
readonly User user;
[ThreadStatic]
static UserScope currentScope;
public UserScope(User user) {
this.user = user;
currentScope = this;
}
public static User User {
get { return currentScope != null ? currentScope.user : null; }
}
public void Dispose() {
///...
}
}
这是我希望工作的一项测试:
static async Task Test() {
var user = new User("Thread Flintstone");
using (new UserScope(user)) {
await Task.Run(delegate {
Console.WriteLine("Crashing with NRE...");
Console.WriteLine("The current user is: {0}", UserScope.User.Name);
});
}
}
static void Main(string[] args) {
Test().Wait();
Console.ReadLine();
}
答案 0 :(得分:7)
在.NET 4.5完整框架中,您可以使用逻辑调用上下文:
static async Task Test()
{
CallContext.LogicalSetData("Name", "Thread Flintstone");
await Task.Run(delegate
{
//Console.WriteLine("Crashing with NRE...");
Console.WriteLine("The current user is: {0}", CallContext.LogicalGetData("Name"));
});
}
static void Main(string[] args)
{
Test().Wait();
Console.ReadLine();
}
但是,您应该只在逻辑调用上下文中存储不可变数据。我有more details on my blog。我已经意味着将它包装到AsyncLocal<T>
库中,但还没有找到时间。