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()

このドメインには少なくとも 1 つのコンテキスト (デフォルトのコンテキスト) がありますが、ContextBoundObject-objects 用に作成された他のコンテキストもある場合があります。Context.DoCallBackマーシャリングされたオブジェクトを呼び出すことにより、任意のドメインを介して、または任意のドメインから暗黙的に、同じドメインでこれらのコンテキストのいずれかに入ることができますContextBoundObjectそれはコンテキストThread.Contextreturnです。

スレッドとドメイン、スレッドとコンテキストの間に親子関係はありません。ただし、ドメインとそのコンテキストの間には厳密な親子関係、1 対多の関係があります。そのため、現在のコンテキストに基づいてドメインを検索する必要はありません。

もう少し遊びたい場合は、私が使用したアプリを次に示します。

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 に答える