Dispatching events into right thread

六月ゝ 毕业季﹏ 提交于 2020-02-07 07:48:49

问题


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
        }
    }
    }
}

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?

Thanks.


回答1:


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.

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.



来源:https://stackoverflow.com/questions/13292628/dispatching-events-into-right-thread

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!