标签:lang span 用户登录 github msdn 操作 master https 直接
简单来说,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>类(https://msdn.microsoft.com/en-us/library/dn906268(v=vs.110).aspx),之所以能够在异步操作之间保存“Local”数据,底下其实也正是利用了ExecutionContext能够在线程的流动之间得以保持,来做到这一点的。(AsyncLocal<T>的源代码参考:https://github.com/dotnet/coreclr/blob/master/src/mscorlib/src/System/Threading/AsyncLocal.cs/#L41)
当然,在大部分场景中,因为有了AsyncLocal<T>类的出现,开发人员不再需要直接使用CallContext.LogicalSetData()/LogicalGetData()了,直接使用AsyncLocal<T>就好了。它更直观。
和AsyncLocal<T>类“相反”的,就是ThreadLocal<T>类。ThreadLocal<T>是为每个不同线程维护一个不同的版本,作用类似[ThreadStatic]。
最后发现题主还问到了ExecutionContext和AppDomain的关系,根据我的了解,ExecutionContext主要是一种基于Thread的东东,和AppDomain应该没有什么关系。标签:lang span 用户登录 github msdn 操作 master https 直接
原文地址:http://www.cnblogs.com/gaobw/p/7845496.html