这不是一个重要的问题,但我想知道为什么 Thread 类公开了一个用于获取当前 Context ( Thread.CurrentContext ) 的属性和一个用于获取当前 AppDomain ( Thread.GetDomain() ) 的方法。
知道 Process > AppDomain > Context > Thread 的层次结构,我的假设是线程的上下文在当前时间点是已知的,并且需要根据当前上下文搜索域。
但我想听到更明智的答案。谢谢!
这不是一个重要的问题,但我想知道为什么 Thread 类公开了一个用于获取当前 Context ( Thread.CurrentContext ) 的属性和一个用于获取当前 AppDomain ( Thread.GetDomain() ) 的方法。
知道 Process > AppDomain > Context > Thread 的层次结构,我的假设是线程的上下文在当前时间点是已知的,并且需要根据当前上下文搜索域。
但我想听到更明智的答案。谢谢!
我的假设是线程的上下文在当前时间点是已知的,并且需要根据当前上下文搜索域。
实际上,在 .NET Framework 的当前实现中,Context
对象保留了对其父域的引用。框架设计者可能已将上下文的域公开为Thread.Context.Domain
. 他们为什么不这样做可能是一个反问;我无法通过查看参考源代码来判断这一点。
重要的是,在任何给定时刻,线程都在特定域内执行代码。这可以是进程的默认域,也可以是通过 输入的域AppDomain.DoCallBack
,AppDomain.ExecuteAssembly
或者是编组的MarshalByRefObject
对象。那将是域Thread.GetDomain()
返回。
这个域至少有一个上下文(默认的),但它也可能有其他的上下文,为ContextBoundObject
-objects 创建的。Context.DoCallBack
通过调用 marshalled ContextBoundObject
-object ,可以通过或从任何域中显式地在同一域上输入任何这些上下文。那就是上下文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,
});
}
}
}