2014-03-31 50 views
3

这不是非常重要的一个问题,但我想知道为什么Thread类的属性获取当前上下文(Thread.CurrentContext)和获得的方法当前的AppDomain(Thread.GetDomain()) 。为什么使用Thread.CurrentContext属性和Thread.GetDomain()方法?

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

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

+1

我敢肯定你的层次的认识是错误的。线程观察上下文。 – Gusdor

+0

'Thread'和'Context'是独立的实体。 Context是与ContextBoundObject对象关联的东西,而不是线程。多个上下文可以通过同一个线程(使用'Context.DoCallBack'),并且多个线程可以共享相同的上下文('Thread.CurrentContext')。你不能“移动”一个线程到另一个域。相关:http://stackoverflow.com/q/22416182/1768303。 – Noseratio

+0

@Noseratio 当然你可以“移动”一个线程到另一个域。来自_Andrew Troelsen的Pro C#5.0和.NET 4.5 Framework_:“作为Windows操作系统线程调度程序和.NET CLR看来,线程可以自由跨越**应用程序域边界。” – Ani

回答

4

我的假设是,对线程上下文在时间上当前 点已知的,域需要基于当前 上下文搜索。

事实上,在目前执行的.NET Framework的Context对象keeps a reference到其父域。框架设计者可能已经将上下文的域名公开为Thread.Context.Domain。这可能是一个反问题,为什么他们不这样做;我无法通过查看参考源代码来了解这一点。

重要的是,在任何给定的时刻,线程正在执行特定域内的代码。这可能是过程的默认域,也可能是通过AppDomain.DoCallBackAppDomain.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, 
       }); 
     } 
    } 
} 
相关问题