8

.NETFrameworkのバージョン4.0以降でExecutionContextが実際にどのように機能するかを調べようとしています。ドキュメントには、Thread.Startおよびほとんどのスレッドプール操作を使用する場合、マネージドプリンシパル、同期、ロケール、およびユーザーコンテキストがすべて新しいスレッドに流れると記載されています。しかし、私はこれが実際に機能しているのをまったく見ることができません。

これは、新しいスレッドを開始するときに同期コンテキストとマネージドプリンシパルが流れるかどうかをテストする単純なコンソールアプリケーションです...

    static void Main(string[] args)
    {
        SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
        Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity("One"), null);

        Thread t1 = new Thread(new ThreadStart(ThreadRun));
        t1.Start();
        t1.Join();

        SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
        Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity("Two"), null);

        AsyncFlowControl aFC = ExecutionContext.SuppressFlow();
        Thread t2 = new Thread(new ThreadStart(ThreadRun));
        t2.Start();
        t2.Join();
        aFC.Undo();

        Console.Read();
    }

    static void ThreadRun()
    {
        Console.WriteLine("ThreadRun Id={0} Context={1} Principle={2}", 
            Thread.CurrentThread.ManagedThreadId, 
            (SynchronizationContext.Current != null), 
            Thread.CurrentPrincipal.Identity.Name);
    }

結果は...

    ThreadRun Id=11 Context=False Principle=One
    ThreadRun Id=12 Context=False Principle=Two

したがって、同期コンテキストはフローせず、マネージドプリンシパルは、指定しない場合でも常にフローします。基本的に、ドキュメントは完全に間違っています。では、ExecutionContextが実際に何をするのか、そしてなぜそれが役立つのかについての説明はありますか?

4

1 に答える 1

9

これはかなり誤解を招くドキュメントです。私はあなたの質問のより広い推力に答えることはできませんが、なぜSynchronizationContext流れないのかをあなたに言うことができます。

Thread.Startのソースを見ると、最終的には次のように呼び出されます。

    [SecuritySafeCritical]
    private void Start(ref StackCrawlMark stackMark)
    {
      this.StartupSetApartmentStateInternal();
      if (this.m_Delegate != null)
        ((ThreadHelper) this.m_Delegate.Target).SetExecutionContextHelper(ExecutionContext.Capture(ref stackMark, ExecutionContext.CaptureOptions.IgnoreSyncCtx));
      this.StartInternal(CallContext.Principal, ref stackMark);
    }

ExecutionContext.CaptureOptions.IgnoreSyncCtxデフォルトでは明示的に渡されることに注意してください。またCallContext.Principal、ExecutionContext.SuppressFlow()に関係なく渡されます。だから、あなたが見ているものを見ている理由を説明しますが、それが役立つかもしれないときや、ドキュメントが完全に間違っている理由は説明しません!

于 2012-03-22T03:27:03.393 に答える