我使用一个带有[ThreadStatic]属性的变量来存储每个套接字的当前活动Session (我使用WebSocket作为连接类型)。在socket 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这里怎么了?
发布于 2020-10-05 08:53:23
任务和线程在很大程度上是不相关的概念,而且重要的是:在大多数有趣的场景中,无论何时await,您都本质上是在改变线程。顺便说一句,这就是为什么不能有一个跨越lock的await,因为编译器知道lock在两边都需要相同的线程。
正因为如此,当您从[ThreadStatic]返回时,任何特定于线程的内容(例如await )都可能无效(除非它恰好是同步操作或已完成操作上的无操作await,或者如果在运行中有一个同步上下文,该上下文正在可靠地将工作推送回同一个线程)。
有一个可能更适合您的场景的AsyncLocal,很大程度上可以被替换为ThreadLocal (还有一些关于方向性的警告),但老实说,只显式地传递状态要简单一些,而不是雄心勃勃地传递状态。
https://stackoverflow.com/questions/64205134
复制相似问题