码迷,mamicode.com
首页 > Web开发 > 详细

.net中ExecutionContext

时间:2017-11-16 18:47:58      阅读:151      评论:0      收藏:0      [点我收藏+]

标签:lang   span   用户登录   github   msdn   操作   master   https   直接   

作者:kaneboy
链接:https://www.zhihu.com/question/50779566/answer/123137983
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

简单来说,ExecutionContext是表示当前的“执行上下文”。当代码进行线程切换时,你可以认为CLR会自动做下面的动作(下面是伪代码):

var oldEc = ExecutionContext.Capture();

ThreadPool.QueueUserWorkItem(() => {
    ExecutionContext.Run(oldEc, () => {
        // 这里才是用户真正需要在另外线程执行代码
    });
});


也就是说,不管用户是使用传统的异步委托(Delegate.BeginInvoke()),还是ThreadPool.QueueUserWorkItem(),还是Task.Run(),CLR在底下都保证会先捕获当前的ExecutionContext,然后在另外的线程上,基于捕获的ExecutionContext继续执行后续的代码。

这样做的目的,就是可以将原有线程上保存的一些上下文数据,比如CallContext里面通过LogicalSetData()保存的自定义数据,和SecurityContext上面保存的用户登录后的凭据数据,传递到后续线程上面,让后续线程能够利用那些数据。这些数据,就可以按照异步代码的逻辑上的流程(而非代码真正的执行流程),来进行(在逻辑上)正确的传递。

.NET 4.6新增的AsyncLocal<T>类(),之所以能够在异步操作之间保存“Local”数据,底下其实也正是利用了ExecutionContext能够在线程的流动之间得以保持,来做到这一点的。(AsyncLocal<T>的源代码参考:

当然,在大部分场景中,因为有了AsyncLocal<T>类的出现,开发人员不再需要直接使用CallContext.LogicalSetData()/LogicalGetData()了,直接使用AsyncLocal<T>就好了。它更直观。

和AsyncLocal<T>类“相反”的,就是ThreadLocal<T>类。ThreadLocal<T>是为每个不同线程维护一个不同的版本,作用类似[ThreadStatic]。

最后发现题主还问到了ExecutionContext和AppDomain的关系,根据我的了解,ExecutionContext主要是一种基于Thread的东东,和AppDomain应该没有什么关系。

.net中ExecutionContext

标签:lang   span   用户登录   github   msdn   操作   master   https   直接   

原文地址:http://www.cnblogs.com/gaobw/p/7845496.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!