別のクラスの別のスレッドから UI を更新する
別のクラスを実行しているスレッドから WPF UI を更新するときによくある問題が発生します。 。長時間の計算中に UI がフリーズするため、ユーザーに進行状況を通知する必要があります。
スレッドとイベントを使用した解決策
サンプル コード:
class MainWindow : Window { private void startCalc() { // Prepare input inputValues input = ...; // Create calculation class and register to its event CalcClass calc = new CalcClass(); calc.ProgressUpdate += (s, e) => Dispatcher.Invoke(() => { /* UI Update */ }); // Start calculation in a separate thread Thread calcthread = new Thread(new ParameterizedThreadStart(calc.testMethod)); calcthread.Start(input); } } class CalcClass { public event EventHandler ProgressUpdate; public void testMethod(object input) { // Raise event to trigger UI update if (ProgressUpdate != null) ProgressUpdate(this, new YourEventArgs(status)); // Notify UI with status updates } }
.NET 4.5 以降の代替手段
新しいものを使用した代替案に従う機能:
タスクの使用: スレッド管理を簡素化するために、スレッドをタスクに置き換えます。
Async/Await の使用: タスクが完了するまで計算を延期します。 UI 更新メソッドを次のようにマークすることで必要になります。非同期。
厳密に型指定された汎用イベントの使用: 厳密に型指定された汎用イベントを使用して、カスタム データ型をイベントに渡します。
拡張機能を使用した改良例:
class MainWindow : Window { Task calcTask = null; // Stores task for later checking void StartCalc() { var calc = PrepareCalc(); calcTask = Task.Run(() => calc.TestMethod(input)); // Start in background } async Task CalcAsync() { var calc = PrepareCalc(); await Task.Run(() => calc.TestMethod(input)); // Await completion } CalcClass PrepareCalc() { // Prepare input and create calc object var calc = new CalcClass(); calc.ProgressUpdate += (s, e) => Dispatcher.Invoke(() => { /* UI Update */ }); return calc; } } class CalcClass { public event EventHandler<EventArgs<YourStatus>> ProgressUpdate; public TestMethod(InputValues input) { // Raise event to trigger UI update ProgressUpdate?.Raise(this, new EventArgs<YourStatus>(status)); // Raise with status } }
追加注:
以上が別のクラスの別のスレッドから WPF UI を安全に更新するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。