Jul*_*anR 3 c# asynchronous threadstatic async-await
我们有一个相当大的现有代码库,用于构建在ASP.NET之上的各种web服务,并且该代码大量使用访问HttpContext.Current.User(包装为Client.User),我相当确定内部使用它[ThreadStatic]来为您提供环境范围.
我目前正在研究是否有可能我们开始以形式使用更多的异步代码,async/await但我很难找到如何使用[ThreadStatic]它.[ThreadStatic]由于其大量使用,实际上不可能消除对依赖的依赖.
我的理解是,当await命中时,代码的执行在那里停止,调用立即返回,并且设置延续以在异步代码返回时继续执行.同时,原始线程可以自由地用于其他事情,例如处理另一个请求.到目前为止我对它的理解.
我无法真正找到一个确定的答案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));
Run Code Online (Sandbox Code Playgroud)
这有Debug.Assert保证会成功吗?
如果另一个请求由与Task.Delay挂起的相同的线程处理,那么该请求将设置一个不同的HttpContext.Current.User,那么在调用continuation时以某种方式存储和恢复的先前状态是什么?
我可以想象的是,在幕后,[ThreadStatic]状态被保存为线程本身的某种字典,并且当一个线程返回到线程池后返回await该字典时,该字典在某处保持安全并且在设置回线程时它执行延续(或者在一个线程上,我不确定它是否一定是处理延续的同一个线程),可能是对屁股的鼓励和"去得到他们的男孩!",但最后部分可能只是我的想象力.
这有点准确吗?
更新:我试图将一个小试验放在一起尝试这个.到目前为止它似乎工作,并且断言没有因为数百个请求中的任何一个而失败.谁能验证测试是否有意义?
async/ await是与线程无关的,这意味着它们具有可在多个不同线程系统中工作的约定.
一般情况下,ThreadStatic在async/中无法正常工作await,除了UI上下文await将在UI线程上恢复等微不足道的情况.对于ASP.NET,ThreadStatic不兼容async.
但是,这HttpContext.Current是一个特例.ASP.NET定义了"请求上下文"(由AspNetSynchronizationContext分配给的实例表示SynchronizationContext.Current).默认情况下,await任务将捕获此同步上下文并使用它来恢复该方法.当方法恢复时,它可能位于不同的线程上,但它将具有相同的请求上下文(包括HttpContext.Current文化和安全性等其他内容).
因此,HttpContext.Current保留,但你自己的任何ThreadStatic价值观都没有.
我在介绍中描述了如何await使用.如果您想了解更多详细信息,请查看我的MSDN文章(特别是异步CTP的最后一节).SynchronizationContextasyncSynchronizationContext
| 归档时间: |
|
| 查看次数: |
1196 次 |
| 最近记录: |