2013-03-19 2 views
23

私はWindows formsアプリケーションでこの機能を使用するにInvokeRequired。どうして?は、WPF

答えて

0

WPFは、各コントロールにUIスレッドにアクセスするのではなく、Dispatcherを使用してメッセージポンプへのアクセスを制御します。

Dispatcher.Invokeを使用して、WPFアプリケーションのUIスレッドに代理人を追加する必要があります。

InvokeRequiredは、winformアプリケーションでは本当に必要ではなく、WPFアプリケーションで確認する必要もありません。 Invokeに電話すると、にはが表示され、UIスレッドには含まれていないはずです。特定のメソッドがUIスレッドから呼び出され、バックグラウンドスレッドから呼び出されることがあります。 1つ選択します。特定のメソッドを呼び出す前に呼び出し元にUIスレッドを呼び出すように強制するか(呼び出す必要がないため)、またはメソッドが呼び出されたときに呼び出し元がUIスレッドにないと想定するかのいずれかです。すでにUIスレッドに入っているときにInvokeを呼び出すことはうまくいきます。 UIスレッドを再起動するときにエラーや問題が発生することはありません(パフォーマンスが非常に低いため、不要なコードを追加しないでください)。あなたがDispatcher.Invoke代わりのInvoke呼び出す必要があるので、WPFではDispatcher.CheckAccess()

+4

もちろん、あなたがスレッドを作成しているかどうかわからないときにチェックしなければならない状況がたくさんあります。 – Christoph

+1

これまでデータバインドが可能なユーザーコントロールを作成しましたか?データは通常、別のスレッドによってフェッチされますが、テキストボックスの値を設定することは、別のコントロールでも行うことができます(例えば、ドロップダウンを変更すると、別のデフォルト値=> UIスレッドになります>データベースからの値の割り当て=>ワーカースレッド上にある) – Christoph

+0

By (WinFormsとWPFの両方で)代わりにBeginInvoke()を使用してください。理由は、Invoke()が醜いデッドロックに陥る可能性があるためです。 – Christoph

1

チェックは、代わりにInvokeRequired

if (!CheckAccess()) { 
    // On a different thread 
    Dispatcher.Invoke(() => log_left_accs(arg)); 
    return; 
} 
9

+0

Invokeについてはどうですか? – oehgr

+0

CheckAccessはディスパッチャのメソッドであり、Windowまたはコントロールのメソッドではありません。 –

+0

@oehgrは 'Dispatcher.Invoke'を使用します。私は自分の返事を更新します – JaredPar

38

WPFでは、Invoke方法はディスパッチャ上でのCheckAccessメソッドを使用します。また、InvokeRequiredプロパティはありませんが、ディスパッチャはCheckAccessメソッドを持っています(なんらかの理由で、インテリセンスに隠されています)。あなたのコードは次のようになります:

delegate void ParametrizedMethodInvoker5(int arg); 
void log_left_accs(int arg) 
{ 
    if (!Dispatcher.CheckAccess()) // CheckAccess returns true if you're on the dispatcher thread 
    { 
     Dispatcher.Invoke(new ParametrizedMethodInvoker5(log_left_accs), arg); 
     return; 
    } 
    label2.Text= arg.ToString(); 
} 
+1

'Dispatcher'の値が' null'である可能性があります。これは、 'DispatcherObject'が' CheckAccess'メソッドを持っている理由です。この可能性を説明しています。 – JaredPar

+0

@JaredPar、どの場合Dispatcherがnullでもかまいませんか?以前はそれを見たことがありませんでした。 –

+0

オブジェクトがフリーズすると、 'Dispatcher'は' null'になると思います。 'DispatherObject.DetachFromDispatcher'への参照を探してください – JaredPar