为什么Thread.CurrentContext属性和Thread.GetDomain()方法?

Ani*_*Ani 4 c# multithreading appdomain threadcontext

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

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

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

nos*_*tio 5

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

实际上,在.NET Framework的当前实现中,该Context对象保持对其父域的引用.框架设计者可能已将上下文的域暴露为Thread.Context.Domain.这可能是一个修辞问题,为什么他们不这样做; 通过查看参考源代码我无法分辨.

重要的是,在任何给定的时刻,线程都在特定域内执行代码.这将是要么进程的默认域,或通过输入域名AppDomain.DoCallBack,AppDomain.ExecuteAssembly或整理MarshalByRefObject-object.这将是域名Thread.GetDomain()返回.

此域至少有一个上下文(默认值),但它也可能具有为ContextBoundObject对象创建的其他上下文.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,
                });
        }
    }
}
Run Code Online (Sandbox Code Playgroud)