0

コールバックを使用してイベントを通知するライブラリのラッパーを開発しました。このコールバックは、UI のスレッドとは別のスレッドを使用して呼び出されるため、ラッパーは次のスクリプトを使用して、イベント ハンドラーを WinForm アプリケーションの適切なスレッドに呼び出します。

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 クラスに相当するもの (クラス、メカニズムなど) はありますか?

ありがとう。

4

1 に答える 1

3

そうですね、これは正しいやり方ではありません。Winforms と WPF には異なる同期プロバイダーがあり、それらは System::Threading::SynchronizationContext::Current にインストールされます。

これを使用するには、コンストラクターで Current 値をコピーします。イベントを発生させる準備ができたら、それがnullptrかどうかを確認します。その場合、オブジェクトはワーカー スレッドで構築され、イベントを直接起動する必要があります。そうでない場合は、Post() メソッドを使用して、UI スレッドでヘルパー メソッドを実行します。そのヘルパーメソッドにイベントを発生させます。

于 2012-11-08T19:01:37.560 に答える