4

私はしばらくの間GUIアプリケーションを書いていますが、私がいつも使用しているのは、クロススレッドアクセスを行うためのMethodInvoker+ラムダ関数です。

私が見つけた例から、私はいつもこのようなものを見ます:

バージョン1

if (InvokeRequired)
{
    Invoke(new MethodInvoker(() => 
    {
        Label1.Text = "Foobar";
    });
}
else
{
    Label1.Text = "Foobar";
}

しかし、これはコードの重複につながります->私にとって大きな悪者です。

では、これの何が問題になっていますか?

バージョン2

MethodInvoker updateText = new MethodInvoker(() => 
    {
        Label1.Text = "Foobar";
    });

if (InvokeRequired)
{
    Invoke(updateText);
}
else
{
    updateText();
}

これで、機能が1つの変数にバンドルされ、Invokeを使用して呼び出すか、必要に応じて関数ポインターとして呼び出します。バージョン2はパフォーマンスの面で劣っていますか?または、これに無名関数を使用するのは悪い習慣ですか?

4

3 に答える 3

10

何も問題はありません...しかし、拡張メソッドを追加して、すべてをいくらか良くすることができます。

public static void InvokeIfNecessary(this Control control,
                                     MethodInvoker action)
{
    if (control.InvokeRequired)
    {
        control.Invoke(action);
    }
    else
    {
        action();
    }
}

次に、次のように書くことができます。

this.InvokeIfNecessary(() => Label1.Text = "Foobar");

ずっときれい:)

必要のないときにデリゲートを作成することには、パフォーマンス上のわずかな欠点がありますが、それはほとんど間違いなく重要ではありません。クリーンなコードの記述に集中してください。

それをしたくない場合でも、既存のコードで変数宣言を簡単にすることができることに注意してください。

MethodInvoker updateText = () => Label1.Text = "Foobar";

new MethodInvokerこれは、別の変数を使用する利点の1つです。ラムダ式に必要なデリゲートのタイプを指示するためのビットは必要ありません...

于 2012-08-14T07:38:09.417 に答える
2

バージョン2はパフォーマンスの面で劣っていますか?または、これに無名関数を使用するのは悪い習慣ですか?

バージョン2の方が優れているわけではありません。パフォーマンスの問題について心配する必要はありません。匿名関数を使用する代わりに、メソッドを定義することもできます。

public void SetLabelTextToFooBar()
{
    Label1.Text = "Foobar";
}

その後:

if (InvokeRequired)
{
    Invoke(SetLabelTextToFooBar);
}
else
{
    SetLabelTextToFooBar();
}

または、メインUIスレッドですべてのコールバック(およびなど)を自動的に実行するBackgroundWorkerを使用するだけで、をチェックする必要がなくなります。RunWorkerCompletedProgressChangedInvokeRequired

于 2012-08-14T07:35:26.547 に答える
2

それを行うための別の練習:

Invoke((MethodInvoker)delegate 
{
     Label1.Text = "Foobar";
});
于 2013-04-23T07:54:04.300 に答える