问题
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