2

これを呼び出す必要があるstring input_ip_r = listView1.Items[lc].SubItems[1].Text; ので、使用しました

if (InvokeRequired)
{
    this.Invoke(new MethodInvoker(function));
    return;
}

これはうまくいきましたが、今はそれを入れてこれBackgroundWorkerを使用しています

if (InvokeRequired)
{
    this.Invoke(new MethodInvoker(bw.RunWorkerAsync));
    return;
}

一度に 1 つしか実行できないというエラーが表示されますBackgroundWorker

では、どのように呼び出しBackgroundworkerますか?

4

2 に答える 2

8

RunWorkerAsync1)呼び出すメソッドとして入れないでください。あなたが考えている方法を実際に実行しているわけではありません。あなたが本当にそこに置くべきものは、次のようなものです:

this.Invoke(new MethodInvoker(MethodToUpdateUI));

MethodToUpdateUIこのコンテキストで行う必要がある UI の更新を具体的に行う新しいメソッドを作成する必要があります。

2) は必要ありませんInvokeRequired。バックグラウンド スレッドにいます。呼び出しは常に必要です。

正直なところ、全体のパターンはif(invoke required) call myself else do stuff私が嫌いな奇妙な構造です。 InvokeRequiredめったに使用しないでください。ほとんどの場合、自分が UI スレッドにいるのかバックグラウンド スレッドにいるのかを把握しておく必要があります。非決定論的であってはなりません)。通常、これはUI スレッドで実行する必要があるメソッドを持つことを意味します。すでに UI スレッドにいる場合は、それらを呼び出すだけです。バックグラウンド スレッドにいて、それがわかっている場合は、Invoke最初に呼び出します。

その上、すでに UI スレッドにいるときに呼び出しても問題なく動作するため、バックグラウンド スレッドにいるか、既に UI スレッドにいるかに関係なく、Invoke単に呼び出しても重大な悪影響はありません。Invoke

3) 通常、ビジネス上の問題を解決するためのコードは UI コードから分離するのが最善です。DoWork のハンドラ内から呼び出しているのはコードの匂いです。これが終わり近くにある場合は、おそらく にイベント ハンドラを追加する必要がありますRunWorkerCompleted。これを定期的に呼び出してワーカーの進行状況で UI を更新する場合は、イベントを使用ReportProgressして処理する必要がありますProgressReported。実行時間の長いタスクで使用する UI から情報を取得するには、バックグラウンド タスクを開始する前に情報にアクセスする必要があります。これらのいずれでもない例外的なケースについては、 を使用するInvokeのが適切かもしれませんが、残りのケースはまれであるべきです。

于 2012-12-19T20:18:49.900 に答える
6

値をどのように使用したいのかよくわかりませんが、例を挙げると、BackgroundWorkerスレッドでこれを簡単に実行できます。

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    string input_ip_r = "";
    this.Invoke(new Action(() => 
    {
        // Don't know what "lc" is (a loop variable?)
        input_ip_r = listView1.Items[lc].SubItems[1].Text;
    }));
}

同じことを行う他の方法については、この回答を参照してください(これは>= .Net 3.5用です)

于 2012-12-19T21:26:39.630 に答える