0

iveはスタックオーバーフローでrevokerequired関連の投稿を高低で検索しました..それは私が多くを学ぶのに役立ちました..しかし私はいくつかの質問があります..invokerequiredだけでなくバックグラウンドワーカーにも関連しています..我慢してください.. :)

私のアプリケーションは何か長いことをし、その過程でGUIを更新する必要があります(プログレスバー、ステータスバー、テキストボックス)。スレッドを使用しましたが、UIを更新するときに恐ろしいクロススレッド例外が発生しました。最近(ちょっと) invokerequiredを適切に使用するコツをつかんだ..[ InvokeRequiredコードパターンの自動化]..この投稿で使用されているコードは次のとおりです。

public static partial class CHelper
{
    public static void InvokeIfRequired(this Control oCtrl, MethodInvoker fnAction)
    {
        if (oCtrl.InvokeRequired)
        {
            oCtrl.Invoke(fnAction);
        }
        else
        {
            fnAction();
        }
    }
}

public partial class Form1 : Form
{
    public void Test()
    {
        this.InvokeIfRequired(() =>
        {
            Text = "Window Title";
            button1.Text = "Hello";
        });
        button1.InvokeIfRequired(() =>
        {
            Text = "Window Title";
            button1.Text = "Hello";
        });
    }
}

これが私が気付いたものです..this.InvokeIfRequiredとbutton1.InvokeIfRequiredはどちらも同じことをします..なぜそうなのですか?button1.InvokeIfRequiredのTextがbutton1のtextプロパティに対応することを期待していましたが、代わりに親フォームを参照しています。私には、これはばかげて、直感的でなく、間違っているように見えます。


別の質問..当時、invokerequiredのコツがわからなかったので、バックグラウンドワーカーを使用してGUIを更新するためにprogressイベントを使用しました。

public partial class Form1 : Form
{
    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        backgroundWorker1.ReportProgress(0, "Hello World");
    }
    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        if (e.UserState != null)
        {
            button1.Text = e.UserState as string;
        }
    }
}

これまでのところ、問題は発生していません。これら2つのアプローチのどちらが優れているか知りたいですか?なぜ?また、以前のInvokeIfRequired関数にデータを渡す方法はありますか?

ありがとう..=)


編集01:親フォームとターゲットコントロールにInvokeを使用することに違いはありますか?..はいform.invokeとcontrol.invokeは同じです..しかし、なぜそうする必要がありますか?直感的ではなく、間違った印象を与えます。

4

1 に答える 1

0

ええと、ボタンコントロールにはまったく関係ありません。Windowsには、ウィンドウのすべての子ウィンドウが同じスレッドによって所有されている必要があるという厳しい規則があります。したがって、そのルールにより、フォームとボタンの両方のBegin / Invoke()メソッドは、正しいスレッドへの呼び出しをマーシャリングします。

Handleプロパティを持たないコンポーネントのプロパティを更新する必要がある場合は、厄介になることに注意してください。ToolStripButtonのように。次に、別のコントロールを選択する必要があります。したがって、一貫性を優先し、常にフォームを使用してください。

そして確かに、BackgroundWorkerを支持してください。それはあなたがあなたの足を撃つことができる方法の数を制限することによってあなたがこれを正しくするのを助けるためのコツを持っています。

于 2012-11-04T05:30:27.717 に答える