1
private void btnUpload_Click(object sender, EventArgs e)
{
    progressbar.value = 10;

    RunLongProcess();

    progressbar.value = 20;

    RunAnotherLongProcess();

    progressbar.value = 50;

    RunOneMoreLongProcess();

    progressbar.value = 100;
}

上記のコードの問題は、アプリケーションがフリーズし、プログレス バーが正しく機能していないことです。

このシナリオに対処する正しい方法は何ですか? 同時に2つのことを実行しようとしていないことを考えると、なぜこれが起こるのかわかりません。それは一度に 1 つのことです。アプリを更新する必要がありますか?

4

1 に答える 1

4

「一度に複数のことを実行」していないという理由だけで、物事がフリーズしています。

ボタン クリックのイベント ハンドラーで実行時間の長いアクションを実行しています。そのイベント ハンドラーが戻るまで、UI はブロックされます。

TaskまたはBackgroundWorkerを使用するなど、長時間実行されるプロセスを別のスレッドに配置してみてください。

他のスレッドは進行状況バーを更新できます。ただし、別のスレッドが UI スレッドに適切にアクセスする必要があることに注意してください。その正確なメカニズムは、WinForms、WPF、または他の何かについて話しているかどうかによって異なります (質問では指定されていません)。

これは、WinForms の非 UI スレッドからコントロールを更新するための私のお気に入りのアプローチです。

https://stackoverflow.com/a/3588137/141172

アップデート

例を次に示します。私は手元に IDE を持っていないので、小さな問題があるかもしれません。

private BackgroundWorker worker = new BackgroundWorker();

public MyForm() // Your form's constructor
{
    InitializeComponent();
    worker.WorkerReportsProgress = true;
    worker.WorkerSupportsCancellation = true;
}

private void btnUpload_Click(object sender, EventArgs e)
{
    if (!worker.IsBusy) // Don't start it again if already running
    {
        // Start the asynchronous operation.
        // Maybe also disable the button that starts background work (btnUpload)
        worker.RunWorkerAsync();
    }
}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    worker.ReportProgress(10);

    RunLongProcess();

    worker.ReportProgress(20);

    RunAnotherLongProcess();

    worker.ReportProgress(50);

    RunOneMoreLongProcess();

    worker.ReportProgress(100); 
}

// This event handler updates the progress. 
private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressbar.value = e.ProgressPercentage;
}

// This event handler deals with the results of the background operation. 
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    // Inform the user that work is complete.
    // Maybe re-enable the button that starts the background worker
}
于 2012-08-27T18:30:55.597 に答える