我们有一个相当大的现有代码库,用于构建在 ASP.NET 之上的各种 web 服务,并且该代码大量使用访问HttpContext.Current.User
(包装为Client.User
),我相当确定在内部使用它[ThreadStatic]
来为您提供环境范围。
我目前正在研究是否有可能我们开始以 的形式使用更多的异步代码,async/await
但我很难找到如何[ThreadStatic]
适应这种情况。由于它的大量使用,消除对它的依赖[ThreadStatic]
是不可能的。
我的理解是,当 anawait
被命中时,代码的执行会停在那里,调用立即返回,并且设置了一个延续以在异步代码返回时继续执行。同时,原始线程可以自由地用于其他事情,例如处理另一个请求。到目前为止我对它的理解。
我无法真正找到明确的答案是HttpContext.Current.User
在await
.
所以基本上:
HttpContext.Current.User = new MyPrincipal();
var user = HttpContext.Current.User;
await Task.Delay(30000);
// Meanwhile, while we wait for that lots of other requests are being handled,
// possibly by this thread.
Debug.Assert(object.ReferenceEquals(HttpContext.Current.User, user));
Debug.Assert
能保证成功吗?
如果另一个请求由与待处理的线程相同的线程Task.Delay
处理,则该请求将设置一个不同的HttpContext.Current.User
,那么当调用 continuation 时,以前的状态是否以某种方式存储和恢复?
我可以想象发生的事情是,在幕后,[ThreadStatic]
状态作为某种字典保存在线程本身上,并且当一个线程在返回后返回线程池时,await
该字典被保存在某个地方安全并返回到线程时它执行延续(或者在一个线程上,我不确定它是否一定是处理延续的同一个线程),可能是在屁股上鼓励拍拍和“去拿他们的男孩!”,但最后部分可能只是我的想象。
这有点准确吗?
更新:我试图组织一个小测试来尝试这个。到目前为止,它似乎有效,并且对于数百个请求中的任何一个,断言都没有失败。任何人都可以验证测试是否有意义?