1

そのため、アプリケーションをマルチスレッド化しました。「クロススレッド操作が無効です: コントロールが作成されたスレッド以外のスレッドからアクセスされました。」というエラーが発生しました。

私のスレッドは、Windows フォーム コントロールを呼び出していました。これを回避するために、私は使用しました

Control.Invoke(new MethodInvoker(delegate { ControlsAction; }));

コードを再利用してアプリをよりきれいにすることができるように、この汎用メソッドを作成する方法を見つけようとしています。

たとえば、呼び出しの際に、リッチ テキスト ボックスを使用して次のことを行います。

rtbOutput.Invoke(new MethodInvoker(delegate {    
rtbOutput.AppendText(fields[0].TrimStart().TrimEnd().ToString() + " Profile not   
removed.  Check Logs.\n"); }));

もう 1 つは、単純にテキストを設定するコンボ ボックスです。

cmbEmailProfile.Invoke(new MethodInvoker(delegate { EmailProfileNameToSetForUsers = 
cmbEmailProfile.Text; }));

もう 1 つの例は、単純にクリアするリッチ テキスト ボックスです。

 rtbOutput.Invoke(new MethodInvoker(delegate { rtbOutput.Clear(); }));

実行したいアクションでコントロールを渡すだけでよい場合に、これを行うことができる汎用関数を作成するにはどうすればよいですか?

これが私たちがこれまでにやってきたことです。

private void methodInvoker(Control sender, Action act)
    {
        sender.Invoke(new MethodInvoker(act));
    }

問題はappendtextのようなもので、気に入らないようです。

4

1 に答える 1

3

このような何かがうまくいくはずです:

public static class FormsExt
{
    public static void InvokeOnMainThread(this System.Windows.Forms.Control control, Action act)
    {
        control.Invoke(new MethodInvoker(act), null);
    }
}

そして、それを使用するのは次のように簡単です。

        var lbl = new System.Windows.Forms.Label();
        lbl.InvokeOnMainThread(() =>
            {
               // Code to run on main thread here
            });

オリジナルのラベルで:

        rtbOutput.InvokeOnMainThread(() =>
            {
               // Code to run on main thread here
               rtbOutput.AppendText(fields[0].TrimStart().TrimEnd().ToString() + " Profile not removed.  Check Logs.\n"); }));
            });
于 2013-04-05T15:09:11.067 に答える