Как does.NET ExecutionContext действительно работает?

Я пытаюсь выяснить, как ExecutionContext фактически работает в версии 4.0 и выше .NET Framework. В документации говорится, что управляемый принцип, синхронизация, языковой стандарт и пользовательский контекст все перетекают в новый поток при использовании потока.Запуск и большинство операций пула потоков. Но я не вижу этого на практике.

вот простое консольное приложение, которое проверяет, если контекст синхронизации и управляемый принцип потока, когда запуск нового потока...

    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 делает в реальности и почему это полезно?

1 ответов


это довольно вводящая в заблуждение документация. Я не могу ответить на более широкий вопрос, но могу сказать почему!--1--> Не поток.

если вы посмотрите на источник нить.Старт, он, в конечном счете, призывает к:

    [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(). Итак, объясняет, почему вы видите то, что видите, но не когда это может быть полезно или почему документы совершенно неверны!