我的假设是,对线程上下文在时间上当前 点已知的,域需要基于当前 上下文搜索。
事实上,在目前执行的.NET Framework的Context
对象keeps a reference到其父域。框架设计者可能已经将上下文的域名公开为Thread.Context.Domain
。这可能是一个反问题,为什么他们不这样做;我无法通过查看参考源代码来了解这一点。
重要的是,在任何给定的时刻,线程正在执行特定域内的代码。这可能是过程的默认域,也可能是通过AppDomain.DoCallBack
,AppDomain.ExecuteAssembly
或编组的MarshalByRefObject
对象输入的域。 这将是域名Thread.GetDomain()
返回。
此域至少有一个上下文(默认值),但它也可能有其他上下文,为ContextBoundObject
对象创建。可以通过Context.DoCallBack
在相同的域上明确地输入任何这些上下文,或者通过调用编组的ContextBoundObject
对象隐式地从任何域输入这些上下文。 那就是背景Thread.Context
返回。
线程和域或线程和上下文之间没有父子关系。但是,域与其上下文之间存在严格的亲子关系,一对多关系。 因此,不需要根据当前上下文来搜索域。
如果你喜欢玩它多一点,这里是我使用的应用程序:
using System;
using System.Runtime.Remoting.Contexts;
using System.Threading;
namespace ConsoleApplication
{
public class Program
{
[Synchronization]
public class CtxObject : ContextBoundObject
{
public void Report(string step)
{
Program.Report(step);
}
}
public static void Main(string[] args)
{
Program.Report("app start");
System.AppDomain domain = System.AppDomain.CreateDomain("New domain");
var ctxOb = new CtxObject();
ctxOb.Report("ctxOb object");
domain.SetData("ctxOb", ctxOb);
domain.DoCallBack(() =>
{
Program.Report("inside another domain");
var ctxOb2 = (CtxObject)System.AppDomain.CurrentDomain.GetData("ctxOb");
ctxOb2.Report("ctxOb called from another domain");
});
Console.ReadLine();
}
static void Report(string step)
{
var threadDomain = Thread.GetDomain().FriendlyName;
Console.WriteLine(
new
{
// Thread.CurrentContext.ContextID is only unique for the scope of domain
step,
ctx = Thread.CurrentContext.GetHashCode(),
threadId = Thread.CurrentThread.ManagedThreadId,
domain = Thread.GetDomain().FriendlyName,
});
}
}
}
我敢肯定你的层次的认识是错误的。线程观察上下文。 – Gusdor
'Thread'和'Context'是独立的实体。 Context是与ContextBoundObject对象关联的东西,而不是线程。多个上下文可以通过同一个线程(使用'Context.DoCallBack'),并且多个线程可以共享相同的上下文('Thread.CurrentContext')。你不能“移动”一个线程到另一个域。相关:http://stackoverflow.com/q/22416182/1768303。 – Noseratio
@Noseratio 当然你可以“移动”一个线程到另一个域。来自_Andrew Troelsen的Pro C#5.0和.NET 4.5 Framework_:“作为Windows操作系统线程调度程序和.NET CLR看来,线程可以自由跨越**应用程序域边界。” – Ani