调用Task后丢失[ThreadStatic]值



我使用一个具有[ThreadStatic]属性的变量来存储每个套接字的当前活动Session(我使用WebSocket作为连接类型(。在套接字connect的开头,我用一个新的Session对象分配它的值,然后执行一个Task方法来获得输出。在Task完成之后,Session的值变为null

ThreadStatic声明:

public class Session
{
...
[ThreadStatic] public static Session _session;
}

要调用的任务方法:

public async Task<string> Connect()
{
var path = Path.Combine(Directory.GetCurrentDirectory(), "storyboard", "1.json");
var json = await File.ReadAllTextAsync(path, Encoding.UTF8);
return $""i":{this.id},"m":"build","a":{json}";
}

任务执行部分:

// Session._session == null ? --> false (here, the value still exists)
var res = await obj.Item1.Execute(met, args); // execute a method with async call
await Session._session.Send(res); // Session._session == null ? --> true

这里怎么了?

任务和线程在很大程度上是不相关的概念,而且重要的是:在最有趣的场景中,任何时候await,您都有可能固有地更改线程。顺便说一句,这就是为什么不能有一个跨越awaitlock,因为编译器知道lock在两侧都需要相同的线程。

正因为如此,当您从await返回时,任何特定于线程的东西,如[ThreadStatic],都可能是无效的(除非它恰好是同步或已完成操作上的无操作await,或者如果正在播放的同步上下文可靠地将工作推回到同一线程(。

有一个AsyncLocal<T>可能更适合您的场景,并且可以将很大程度上替换为ThreadLocal(在方向性方面有一些注意事项(,但老实说,更简单的做法是显式地传递状态,而不是模糊地传递状态。

相关内容

  • 没有找到相关文章

最新更新