問題:
データベース操作が長時間実行されると、メイン アプリケーション ウィンドウがフリーズし、進行状況バーが応答しなくなる可能性があります。これは、データベース タスクがメイン UI スレッドをブロックするために発生します。
BackgroundWorkers とマルチスレッド:
BackgroundWorker
クラスは、時間のかかるタスクを別のスレッドにオフロードし、UI の応答性を維持することで解決策を提供します。 ただし、このバックグラウンド スレッドから UI の更新を正しく管理することが重要です。
UI を安全に更新する:
UI 要素を変更するには、メインスレッドのディスパッチャーを使用する必要があります。 バックグラウンド スレッドから UI コントロールを直接更新するのは安全ではなく、エラーが発生します。
解決策:
フリーズの問題を解決するには、プログレスバーの更新専用の BackgroundWorker
を使用します。これにより、データベース操作ワーカーが分離され、競合が防止されます。
コードの実装:
MainWindow.xaml: データベース操作の BackgroundWorker
.
専用のプログレス バー ワーカー: プログレス バーの更新を管理する新しいクラスを作成します:
<code class="language-csharp">public class ProgressBarWorker { private ProgressBar progressBar; private BackgroundWorker worker; public ProgressBarWorker(ProgressBar progressBar) { this.progressBar = progressBar; worker = new BackgroundWorker(); worker.WorkerReportsProgress = true; worker.DoWork += Work; worker.ProgressChanged += ProgressChanged; // Added ProgressChanged handler } public void Run() { worker.RunWorkerAsync(); } private void Work(object sender, DoWorkEventArgs e) { // Simulate long-running work; replace with your database operation for (int i = 0; i < 100; i++) { Thread.Sleep(100); // Simulate work worker.ReportProgress(i); // Report progress to the main thread } } private void ProgressChanged(object sender, ProgressChangedEventArgs e) { progressBar.Value = e.ProgressPercentage; // Update progress bar on main thread } }</code>
MainWindow コード (例): UserControl_Loaded
イベントで、ProgressBarWorker
:
<code class="language-csharp">ProgressBarWorker progressBarWorker = new ProgressBarWorker(progressBar); progressBarWorker.Run();</code>
利点:
以上が長時間実行されるデータベース操作に BackgroundWorkers を使用するときに UI のフリーズを防ぐにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。