2

フォームからバックグラウンド ワーカーを開始したい。

    private void button2_Click(object sender, EventArgs e)
    {
        backgroundWorker2.RunWorkerAsync();
    }

    private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
    {
        ExtClass.doit("Hello", "World");
    }

バックグラウンド ワーカーは、テキスト ボックスに「Hello World」を挿入します。

    public static void doit(string a, string b)
    {
        Form F1 = Application.openForms[0] as Form1;
        F1.textbox1.Text = a + b;
    }

しかし、例外が発生します。バックグラウンド ワーカーからフォーム コントロールにアクセスするにはどうすればよいですか?

4

5 に答える 5

2

バックグラウンド ワーカーは、(名前が示すように) バックグラウンドで作業を行います。

すべてのControlオブジェクトは、スレッド セーフにならないように設計されています。それらを作成したスレッド (通常は UI スレッドと呼ばれます) からのみアクセスできます。

UI スレッドでコード ブロックを実行する方法はいくつかありますが、最初に設計の基本的な部分を確認する必要があります。バックグラウンド ワーカーを使用するという考え方は、バックグラウンドで作業を行うことです。ユーザー インターフェイスとの対話を伴わ ない作業。

作業を行うために UI から情報を取得する必要がある場合は、バックグラウンド ワーカーを開始する前に情報を取得し、その情報を引数として work メソッドに渡す必要があります。操作の結果で UI を更新する場合は、completed イベント ハンドラーを使用する必要があります。(これは常に UI スレッドで実行されます。BGW クラスが処理します。) プログレス バーまたはラベルを進行状況で更新する必要がある場合は、progress updated イベントを使用し、BGW で update progress を呼び出す必要があります。進行状況の更新イベントも UI スレッドで実行されます。

于 2012-11-16T17:43:03.280 に答える
1
F1.Invoke(new MethodInvoker(()=> { F1.textbox1.Text = a + b; }));
于 2012-11-16T17:41:24.890 に答える
0

この問題を解決するには、フィールドがないため、フィールドがなく、これが例外のソースであるためForm1、への参照ではなく参照を作成する必要があります。これを変更する必要があります。FormFormtextBox1Form1

Form F1 = Application.OpenForms[0] as Form1;

これに

Form1 F1 = Application.OpenForms[0] as Form1;

次に、必要に応じて、別のスレッドからアクセスしているため、textBox1フィールドへのアクセスを呼び出す必要があります(DoWorkは別のスレッドで実行されますが、RunWorkerCompletedはUIスレッドにあります)。したがって、完全なコードは次のようになります。

public static void doit(string a, string b)
{
    Form1 F1 = Application.openForms[0] as Form1;
    if(F1.InvokeRequired)
        F1.Invoke(new MethodInvoker(delegate() { F1.Text = a + b; });
    else
        F1.Text = a + b;
}
于 2012-11-16T18:03:02.810 に答える
0

少し助けが必要です。

他のc#プロジェクトでバックグラウンドワーカーを実行しています。問題は、このプロジェクトには、バックグラウンドワーカーが実行時にアクセスする巨大なコンボボックスとテキストボックスがあることです。

では、すべてをに配置せずにGUIでコントロールにアクセスするにはどうすればよいですか。

textbox1.Invoke(new MethodInvoke(()............})); オプション...

于 2012-11-20T12:05:50.220 に答える
0

フォームへの参照が必要であり、フォームを変更するメソッドで渡す Invoke または Begin/End Invoke を使用する必要があります。

参照を保持するには、コントロールを渡すRunWorkerAsync(Object)を使用し、 DoWork Arg のArgumentを介して参照を取得することをお勧めします。

于 2012-11-16T17:41:25.980 に答える