2016-10-29 10 views
0

私には、ValueGeneratedという名前のイベントがあります。 ValueGeneratedを生成し、発生させるコードはスレッド内で実行されており、このイベントを受け取るメソッドはform.control(つまりフォーム)上にあります。 UIスレッドが別のスレッドがUIを変更することはできませんので、私は、イベントの生成に以下のコードを書いた:イベントのターゲットを取得する方法

if (ValueGenerated.Target is System.windows.form.control) 
{ 
Control targetForm = ValueGenerated.Target as control; 
targetForm.Invoke(ValueChanged,new object[]{this,args}); 
} 

しかし、私は、イベントが複数のMethodeのことで登録されている場合はどうなるかと思います。たとえば、2つまたは3つの宛先によって。なぜ、イベントとデリゲートクラスには、最後のメソッドのインスタンスオブジェクトを返すTargetプロパティが追加されていますか?私たちは常に最後のものだけを必要としますか?

+0

GetInvocationListを使用して、登録されたすべての代理人を取得します。それから、ターゲットを確認するためにそれらをすべて検査することができます。 –

+0

他のスレッドからUIを更新できないという人は誰ですか? – Jim

+1

イベントの実際のバッキングストアはMulticastDelegateです。複数の加入者を許可することによって、代議員を拡張します。潜在的なスレッドのバグを隠すことは非常に悪い考えです。特にInvoke()はデッドロックの原因となるので、イベントハンドラメソッドには戻り値がないため、デッドロックは必要ありません。特にUIに影響を及ぼすイベントは、ワーカースレッドが動作し続けているのにユーザがウィンドウを閉じたときに間違ってしまうことがよくあります。それをしないでください。 –

答えて

2

あなたは間違っています。

コメントに記載されているように、デリゲートインスタンスでGetInvocationList()を呼び出すと、呼び出し対象の完全なリストを取得できます。次に、各ターゲットを個別に呼び出すことができます。

しかし、これはではありません。正しい方法です。あなたのイベントは、すべてのハンドラを同じように処理する必要があります。イベントは、バックグラウンドスレッドで上昇常にあるイベントの一種であり、そしてそれは常には、UIスレッドにディスパッチするための適切なメカニズムを使用する必要があり、その後、常にUIオブジェクトが扱う場合

。この種のデザインの例については、ProgressChangedRunWorkerCompletedのイベントについては、BackgroundWorkerクラスを参照してください。

これらの条件のいずれかが真でない場合、イベントはどのような方法でもクロススレッド呼び出しを処理しないでください。スレッドアフィニティを持つイベントのサブスクライバは、それ自体を処理することが期待されます。

残念ながら、それ以上の具体的なアドバイスを提供するための十分な文脈はありません。唯一明らかなことは、行き止まりの道を歩み始めたことです。向きを変え、戻ってきて、より滑らかな道を進む。 :)

+0

私はこの解決策はOKだと思います。しかし、私はBackgroundWorkerの操作をコンポーネントとして欲しがっています。たとえば、sin(t)のような関数を100ミリ秒ごとに計算し、関数の値を含むイベントを発生させるコンポーネントが必要です。このイベントは、ゲージのようなグラフィックコントロールによって使用され、ユーザーに表示されます。私はフォーム上にドロップされる可能性が高いコンポーネントとしてこの信号ジェネレータを持っていたい。 BackgroundWorkerから拡張することをお勧めしますか? – Pat928

+0

具体的な例として、1)長時間実行される操作は、「BackgroundWorker」には適していません。なぜなら、スレッドプールスレッドを結びつけているからです.2)単にtrig関数を計算する操作は、スレッドアフィニティドオブジェクトへのアクセス、およびそのようなコンポーネント内のスレッドアフィニティ機能の使用は、不当で複雑すぎるようです。つまり、その例では、おそらくC#の 'event'は、とにかくその振る舞いを表現する最良の方法ではないかもしれません。ループと 'await Task.Delay(100) 'を呼び出すと' async'メソッドのように思えます。 –

+0

いいえ、あなたはそれを得ていませんでした。値を生成するコンポーネントが必要です。このイベントを受け取るためにこのコンポーネントに登録するリスナーがあります(回路のコンポーネントの信号を生成するクロックパルスジェネレータのように)。値の生成は他によって制御されず、値コールに応答して取得されません(あなたの命題と最終的には非同期) – Pat928

関連する問題