6

这不是一个重要的问题,但我想知道为什么 Thread 类公开了一个用于获取当前 Context ( Thread.CurrentContext ) 的属性和一个用于获取当前 AppDomain ( Thread.GetDomain() ) 的方法。

知道 Process > AppDomain > Context > Thread 的层次结构,我的假设是线程的上下文在当前时间点是已知的,并且需要根据当前上下文搜索域。

但我想听到更明智的答案。谢谢!

4

1 回答 1

6

我的假设是线程的上下文在当前时间点是已知的,并且需要根据当前上下文搜索域。

实际上,在 .NET Framework 的当前实现中,Context对象保留了对其父域的引用。框架设计者可能已将上下文的域公开为Thread.Context.Domain. 他们为什么不这样做可能是一个反问;我无法通过查看参考源代码来判断这一点。

重要的是,在任何给定时刻,线程都在特定域内执行代码。这可以是进程的默认域,也可以是通过 输入的域AppDomain.DoCallBackAppDomain.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,
                });
        }
    }
}
于 2014-03-31T12:01:40.170 回答