gpt4 book ai didi

c# - [ThreadStatic] 的使用与异步代码不一致吗?

转载 作者:行者123 更新时间:2023-11-30 13:37:02 25 4
gpt4 key购买 nike

我们有一个相当大的现有代码库,用于构建在 ASP.NET 之上的各种网络服务,该代码大量使用访问 HttpContext.Current.User(包装为 Client.User ),我相当确定它在内部使用 [ThreadStatic] 来为您提供环境范围。

我目前正在研究是否有可能开始以 async/await 的形式使用更多异步代码,但我很难找到如何使用 [ThreadStatic] 适合这个。由于它的大量使用,消除对 [ThreadStatic] 的依赖实际上是不可能的。

据我了解,当 await 被命中时,代码的执行将停止在那里,调用立即返回,并且设置了一个延续以在异步代码返回时继续执行。同时,原始线程可以自由地用于其他事情,例如处理另一个请求。到目前为止我对它的理解。

我真的找不到明确的答案是 HttpContext.Current.User 是否保证在 之前和之后相同等待

所以基本上:

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,因此是当继续被调用时,以前的状态以某种方式存储和恢复?


我能想象发生的事情是,在幕后,[ThreadStatic] 状态作为某种字典保存在线程本身上,并且当线程在返回后返回到线程池时await 该字典在某处保持安全,并在执行延续时设置回线程(或在 a 线程上,我不确定它是否一定是 同一个处理续集的线程),可能是在拍拍屁股和说“加油,男孩!”,但最后一部分可能只是我的想象。

这有点准确吗?

更新:我试图组织一个小测试来尝试这个。到目前为止,它似乎有效,并且断言在数百个请求中都没有失败。谁能验证测试是否有意义?

https://gist.github.com/anonymous/72d0d6f5ac04babab7b6

最佳答案

async/await 与线程无关,这意味着它们具有可以在多个不同线程系统中工作的约定。

一般来说,ThreadStatic 将无法在 async/await 中正常工作,除了微不足道的情况,例如 await 将在 UI 线程上恢复。对于 ASP.NET,ThreadStaticasync 不兼容。

但是,HttpContext.Current 是一个特例。 ASP.NET 定义了“请求上下文”(由分配给 SynchronizationContext.CurrentAspNetSynchronizationContext 实例表示)。默认情况下,await任务将捕获此同步上下文并使用它来恢复该方法。当方法恢复时,它可能在不同的线程上,但它将具有相同的请求上下文(包括 HttpContext.Current 以及文化和安全等其他内容).

因此,HttpContext.Current 被保留,但您自己的任何 ThreadStatic 值都没有。

我在 async intro 中描述了 await 如何与 SynchronizationContext 一起工作.如果您想了解更多详细信息,请查看我的 SynchronizationContext MSDN article (particularly the last section on the async CTP) .

关于c# - [ThreadStatic] 的使用与异步代码不一致吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26516730/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com