2

BackgroundWorker時間のかかる操作を実行するプロセスを実行するアプリケーションの一部をコーディングしようとしています。メインスレッドでは、タイマーが進行状況バーを更新します (これはこの質問の続きです)。ただし、このコードは no を表示しますMessageBoxesforeach (String word in this.words)イベント ハンドラーの行にブレークポイントを設定すると、値がないSearchButton_Clickことがわかります。this.wordsthis.words.Count() == 0

public partial class Form1 : Form
{
    System.Windows.Forms.Timer searchProgressTimer;
    List<String> words;

    public Form1()
    {
        InitializeComponent();

        words = new List<String>(3);
    }

    private void SearchDatabase_Click(object sender, EventArgs e)
    {
        this.searchProgressTimer.Start();
        SearchBackgroundWorker.RunWorkerAsync();

        foreach (String word in this.words) // BREAKPOINT HERE
            MessageBox.Show(word);
    }

    private void SearchBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        // Time-consuming operation
        String filename = @"http://www.bankofengland.co.uk/publications/Documents/quarterlybulletin/qb0704.pdf";
        WebClient webClient = new WebClient();
        webClient.DownloadFileAsync(new Uri(filename), @"file.pdf");
        List<String> word_result = new List<String> { "word1", "word2", "word3" };
        e.Result = word_result; // e.result is an Object, and word_result is a List.
    }

    private void SearchBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        this.searchProgressTimer.Stop();
        this.searchProgressBar.Value = 0;
        this.words = (List<String>)e.Result;
    }   
}

これが発生する理由についての私の推測はBackgroundWorker、メイン UI スレッドがforeachループに移動する前にスレッドの操作が終了していないためです。その部分は理解できたと思います。ただし、時間のかかる操作をバックグラウンド スレッドで実行して、進行状況バーがその操作の実行時に値を更新できるようにしたいので、BackgroundWorker終了直後の結果を使用するにはどうすればよいですか?

要点が伝わらない場合は、タイトルを編集してください。これをどう表現していいのかわからなかった。

4

1 に答える 1

7

その RunWorkerCompleted イベントでやりたいことは何でもします。

private void SearchBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    this.searchProgressTimer.Stop();
    this.searchProgressBar.Value = 0;
    this.words = (List<String>)e.Result;

    foreach (String word in this.words) // BREAKPOINT HERE
        MessageBox.Show(word);
}

この情報はバックグラウンド ワーカーから取得しているため、リストがあることを知る唯一の方法は、ワーカーが完了したときです。

于 2012-07-13T20:08:53.827 に答える