将事件调度到正确的线程中 [英] Dispatching events into right thread

查看:76
本文介绍了将事件调度到正确的线程中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为使用回调函数通知事件的库开发了一个包装器。此回调使用不同于UI线程的另一个线程调用,因此包装器使用以下脚本将事件处理程序调用到WinForm应用程序的正确线程中。

I have developed a wrapper for a library that uses a callback to notify events. This callback is called using another thread than UI's thread, so the wrapper uses the following script to call the event handlers into the right thread for a WinForm application.

void AoComm::Utiles::Managed::DispatchEvent( Delegate^ ev, Object^ sender, Object^ args )
{
ComponentModel::ISynchronizeInvoke^ si;
array<Delegate^>^ handlers;

if(ev != nullptr)
{
    handlers= ev->GetInvocationList();

    for(int i = 0; i < handlers->Length; ++i)
    {
        // target implements ISynchronizeInvoke?
        si = dynamic_cast<ComponentModel::ISynchronizeInvoke^>(handlers[i]->Target);
        try{
            if(si != nullptr && si->InvokeRequired)
            {
                IAsyncResult^ res = si->BeginInvoke(handlers[i], gcnew array<Object^>{sender, args});
                si->EndInvoke(res);

            }else{
                Delegate^ del = handlers[i];
                del->Method->Invoke( del->Target, gcnew array<Object^>{sender, args} );
            }
        }catch(System::Reflection::TargetException^ e){
            Exception^ innerException;
            if (e->InnerException != nullptr)
            {
                innerException = e->InnerException;

            }else{
                innerException = e;
            }
            Threading::ThreadStart^ savestack = (Threading::ThreadStart^) Delegate::CreateDelegate(Threading::ThreadStart::typeid, innerException, "InternalPreserveStackTrace", false, false);
            if(savestack != nullptr) savestack();
            throw innerException;// -- now we can re-throw without trashing the stack
        }
    }
    }
}

这段代码很好用,但是我已经读过WPF的Dispatcher类,它的功能与我的代码相同(当然还有更多)。
那么,是否有与WinForms的Dispatcher类等效的类(类,机制等)?

This code works pretty well, but I have read about Dispatcher class for WPF that do the same than my code (and more, of course). So, is there something (class, mechanism, ...) equivalent to Dispatcher class for WinForms?

谢谢。

推荐答案

对,这不是正确的方法。 Winforms和WPF具有不同的同步提供程序,它们将它们安装在System :: Threading :: SynchronizationContext :: Current中。

Right, this isn't the right way to do it. Winforms and WPF have different synchronization providers, they install theirs in System::Threading::SynchronizationContext::Current.

要使用它,请在构造函数中复制Current值。准备好触发事件时,请检查事件是否为 nullptr 。如果是这样,则您的对象是在辅助线程中构造的,则应直接触发事件。如果不是,则使用Post()方法在UI线程上运行辅助方法。让那个辅助方法触发事件。

To use it, copy the Current value in your constructor. When you are ready to fire the event, check if it is nullptr. If it was then your object got constructed in a worker thread and you should fire your event directly. If it isn't then use the Post() method to run a helper method on the UI thread. Have that helper method fire the event.

这篇关于将事件调度到正确的线程中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆