2

これは私がこれまでに試したことです:

  1. button.Visible = falseフォームの初期化子に入れbutton.Visible = trueて、backgroundWorkersのDoWorkイベントの最後に置きます。
    これにより、BackgroundWorkerが作業を行った後、プログラムがフリーズします。
    理由がわかりません。

  2. フォームの初期化子button.Visible = falseに入れbutton.Visible = trueて、呼び出しの後に入れbackgroundWorker1.RunWorkerAsync()ます。
    BackgroundWorkerが作業を開始した直後にボタンが表示されるため、これは正しく機能しません。
    私はこれがなぜ起こっているのか理解しています。

  3. フォームのイニシャライザーbutton.Visible = falsedoneEvent = new AutoResetEvent(false)入れdoneEvent.WaitOne()button.Visible = trueから、backgroundWorker1.RunWorkerAsync()呼び出しの後に入れます。
    このように、フォームにあるProgressBarが正しく機能しなくなることを除いて、すべてが正常に機能します(すべての作業が完了するまで進行状況は表示されません)。
    なぜこれが起こっているのか直感的に理解できるかもしれませんが、私はそれを本当に理解しておらず、それを解決する方法もわかりません。
4

1 に答える 1

5

このコードはボタンが作成されたスレッドとは異なるスレッドにあるため、コードがDoWorkイベント内で実行されている間は、ボタンのメソッド/プロパティを呼び出さないでください。BackgroundWorkwer
は 、明確に定義された一連のイベントを使用して、インターフェイスを更新する必要があり、そのタスクにこれらのイベントを使用する必要がある状況を処理します。

たとえば、プロパティWorkerReportsProgressをtrueに設定し、イベントをサブスクライブし、DoWorkイベント内 ProgressChangedで呼び出して、バックグラウンド作業の進行中にインターフェイスを更新できます。backgroundWorker1.ReportProgress(...);

あなたの場合、おそらくあなたはイベントを購読し、そのイベントRunWorkerCompletedであなたのボタンを表示する必要があります

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if (!e.Cancelled && e.Error == null)
    {
        button.Visible = true; 
    }
}

BackgroundWorkerのMSDNページへのリンクには、DoWorkイベントが複雑なタスクを実行しているときにプログレスバーを更新する方法を示すサンプルがあります。

于 2012-12-08T16:14:46.530 に答える