3

いくつかのコードを維持しているときに、バックグラウンドワーカーに無限のハングアップがあることを発見しました。ワーカーには、スクリプトファイルへのアクセスが必要です。元のコードは、スクリプトファイルが定義されていない場合にファイルダイアログをポップアップして、ユーザーが選択できるようにするために作成されました。これは次のようになります。

private void bgworker_DoWork(object sender, DoWorkEventArgs e)
{
    ... snip ...

    if (String.IsNullOrWhitespace(scriptFile))
    {
         scriptFile = PromptForScript();
    }

    ... snip ...
}

private string PrompForScript()
{
    string script = "";
    OpenFileDialog openDialog = new OpenFileDialog();

    if (openDialog.ShowDialog() == DialogResult.OK)
    {
        script = openDialog.FileName;
    }

    return script;
}

について少し読みましたMethodInvokerが、ほとんどすべてのinvokeメソッドでは、コントロールから呼び出す必要があります。問題のバックグラウンドワーカーは、拡張されていない別のクラスから実行されていますControl。そのためにbgworkerでクラスを呼び出すフォームを使用しますか?または、ユーザー入力のためにスレッドを中断する別の方法はありますか?

4

4 に答える 4

3

バックグラウンドワーカーのDoWorkイベントハンドラーからUIを呼び出すことはお勧めしません。 BackgroundWorkerUIの応答性を維持するために、UI以外のスレッドで作業を行うことを目的としています。BackgroundWorkerオブジェクトを。で開始する前に、ファイル情報を要求する必要がありますRunWorkerAsync

于 2012-05-16T18:45:14.683 に答える
1

実行したいのは、UIスレッドでSynchronizationContextをキャプチャし、それをバックグラウンドワーカーに渡すことです。BackgroundWorkerは、コンテキストでSend()(synchronous、like Invoke)およびPost()(asynchronous、like BeginInvoke)を呼び出して、正しいUIスレッドに呼び出すことができます。そうは言っても、この場合、BackgroundWorkerはおそらく必要ありません。通常のスレッドプールスレッドで十分です。

http://msmvps.com/blogs/manoj/archive/2005/11/03/74120.aspxからのこの(わずかに変更された)コードのブロックは、あなたに一般的な考えを与えるはずです:

private void button1_Click(object sender, EventArgs e)
{
    // Here we are on the UI thread, so SynchronizationContext.Current
    // is going to be a WindowsFormsSynchronizationContext that Invokes properly
    ctx = SynchronizationContext.Current;
    ThreadPool.QueueUserWorkItem(
        // This delegate is going to be invoked on a background thread
        s => {
            // This uses the context captured above to invoke
            // back to the UI without the "messy" referencing 
            // of a particular form
            ctx.Send(s2 =>
            {
               // Interact with your UI here- you are on the UI thread
            },null);
        }
    );
}
于 2012-05-16T18:45:32.367 に答える
0

一部のフォームがBGworkerを使用する別のクラス内で長時間実行されるプロセスを開始する場合、フォーム(またはUIアーキテクチャによってはプレゼンター)がエラー状態の処理を処理しないのはなぜですか?

おそらく、ステータスの結果を返すだけですか(または、UIで処理できる非常にターゲットを絞った特定の例外をスローします)?

バックグラウンドワーカーにエラーがあるかどうかを判断させますが、エラー(特にメッセージボックスを表示するUI部分)を上位層に渡します。

申し訳ありませんが、これには具体的なコードはありませんでしたが、システムの設計方法によっては、さまざまな方法で使用できる可能性があります。

于 2012-05-16T18:54:33.777 に答える
-2

クラスFormにはInvokeメソッドがあるので、フォームインスタンスをバックグラウンドの作業クラスに渡すと機能するはずです。

于 2012-05-16T18:40:24.270 に答える