34

アプリケーションでこの関数を使用しましたWindows forms

delegate void ParametrizedMethodInvoker5(int arg);

private void log_left_accs(int arg)
{
    if (InvokeRequired) 
    {
        Invoke(new ParametrizedMethodInvoker5(log_left_accs), arg);
        return;
    }

    label2.Text = arg.ToString();
}

しかし、それではWPF機能しません。なんで?

4

4 に答える 4

67

WPF では、メソッドはディスパッチャ上にあるため、代わりにInvokeを呼び出す必要があります。また、プロパティはありませんが、ディスパッチャーにはメソッドがあります (なぜかインテリセンスに隠されています)。したがって、コードは次のようになります。Dispatcher.InvokeInvokeInvokeRequiredCheckAccess

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();
}
于 2013-03-19T16:21:13.657 に答える
21

WPF では、CheckAccess代わりにメソッドを使用しますInvokeRequired

if (!CheckAccess()) { 
  // On a different thread
  Dispatcher.Invoke(() => log_left_accs(arg));
  return;
}
于 2013-03-19T16:19:50.123 に答える
0

チェックDispatcher.CheckAccess()

于 2013-03-19T16:19:23.563 に答える
-1

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

Dispatcher.InvokeWPF アプリケーションの UI スレッドにデリゲートを追加するために使用する必要があります。

またInvokeRequired、Winform アプリでは実際には必要なく、WPF アプリケーションで確認する必要もないことにも注意してください。を呼び出すときは、UI スレッドにいないことを知っておく必要がありますInvoke。特定のメソッドが UI スレッドから呼び出されることもあれば、バックグラウンド スレッドから呼び出されることもあります。いずれかを選択してください。特定のメソッドを呼び出す前に常に呼び出し元に UI スレッドを呼び出すように強制する (呼び出す必要がないようにする) か、メソッドが呼び出されたときに呼び出し元が UI スレッドにいないと想定します。呼び出すことも注目に値します。Invoke既に UI スレッドにいる場合は問題ありません。UI スレッドの再呼び出しの偶発的なインスタンスに起因するエラーや問題はありません (非常にわずかなパフォーマンス コストがあるため、必要のないコードをあちこちに追加しないでください)。

于 2013-03-19T16:19:15.130 に答える