本文介绍了什么时候在UI应用程序中调用SynchronizationContext.SetSynchronizationContext()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习SynchronizationContext类.我试图了解在WinForm/WPF应用程序的上下文中调用SynchronizationContext.SetSynchronizationContext()的常见用法方案.设置线程的SynchronizationContext是什么意思?我什么时候应该做,为什么?另外,如果我设置了它,是否应该在某个时候取消设置?

I'm learning about the SynchronizationContext class. I'm trying to understand what are the common usage scenarios for calling SynchronizationContext.SetSynchronizationContext() in the context of a WinForm/WPF application. What does it mean to set the SynchronizationContext of a thread? When should I do it and why? Also, if I set it, should I unset it at some point?

@Hans Passant在他的回答中问我为什么要考虑SetSynchronizationContext().我的想法是在工作线程上设置上下文,以便在该线程上运行的代码具有要使用的上下文.

In his answer, @Hans Passant asked why I was contemplating SetSynchronizationContext(). The idea I have is to set the context on a worker thread so that code running on that thread will have a context to use.

private void button3_Click(object sender, EventArgs e)
{
    var syncContext = SynchronizationContext.Current;
    Task.Factory.StartNew(() =>
    {
        // Setup the SynchronizationContext on this thread so
        // that SomeAsyncComponentThatNeedsACurrentContext
        // will have a context when it needs one
        if (SynchronizationContext.Current == null)
            SynchronizationContext.SetSynchronizationContext(syncContext);

        var c = new SomeAsyncComponentThatNeedsACurrentContext();
        c.DoSomething();

    });
}

推荐答案

通常应将其留给特定的UI类库以正确设置. Winforms自动安装WindowsFormsSynchronizationContext实例,WPF安装DispatcherSynchronizationContext,ASP.NET安装AspNetSynchronizationContext,Store应用程序安装WinRTSynchronizationContext,等等.高度特定的同步提供程序,已调整为UI线程分配事件的方式.

You should in general leave it up to the specific UI class library to set this correctly. Winforms automatically installs a WindowsFormsSynchronizationContext instance, WPF installs a DispatcherSynchronizationContext, ASP.NET installs a AspNetSynchronizationContext, a Store app installs WinRTSynchronizationContext, etcetera. Highly specific synchronization providers that are tuned to the way the UI thread dispatches events.

这些应用程序环境使用其主线程的方式有一些特殊之处.它们都实现一个调度程序循环,并使用线程安全队列来接收通知. Windows GUI编程中通常称为消息循环".这是解决生产者/消费者问题的通用解决方案,其中调度程序循环实现了消费者.

There's something special about the way these application environments use their main thread. They all implement a dispatcher loop and use a thread-safe queue to receive notifications. Generally known as the "message loop" in Windows GUI programming. This is a generic solution to the producer/consumer problem, with the dispatcher loop implementing the consumer.

为工作线程创建自己的同步提供程序首先需要这样的线程实现相同的机制.换句话说,您将需要一个线程安全队列,例如ConcurrentQueue,并且需要编写线程以从队列中检索通知并执行它们.委托对象将是一个不错的选择.现在,实现Post方法将没有问题,只需将SendOrPostCallback委托添加到队列中即可.实现Send方法需要额外的工作,线程需要发信号通知该委托已被检索并执行.因此,队列对象还需要一个AutoResetEvent.

Creating your own synchronization provider for a worker thread first requires that such a thread implements this same mechanism. In other words, you will need a thread-safe queue, like ConcurrentQueue, and the thread needs to be written to retrieve notifications from the queue and execute them. A delegate object would be a good choice. You will now have no problem implementing the Post method, simply add the SendOrPostCallback delegate to the queue. Extra work is required to implement the Send method, the thread needs to signal back that the delegate was retrieved and executed. So the queue object also needs an AutoResetEvent.

请注意您的线程现在如何不再成为一般有用的线程,由于不得不分派这些通知而使其陷入困境.现有的同步提供程序如何完成所有这些工作.因此,如果您的应用程序是Winforms应用程序,那么您最好在工作线程中使用虚拟的不可见形式调用Application.Run().您将自动免费获得其同步提供程序.

Do note how your thread now stops becoming a generally useful thread, it is bogged down by having to dispatch these notifications. And how the existing synchronization providers already do all of this. So if your app is a Winforms app then you might as well call Application.Run() on your worker thread with a dummy invisible form. And you'll automatically get its synchronization provider for free.

这篇关于什么时候在UI应用程序中调用SynchronizationContext.SetSynchronizationContext()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-14 21:28