5

私は WPF アプリに取り組んでおり、タスクの実行前後にカーソルを変更したいだけです。私はこのコードを持っています:

this.Cursor = Cursors.Wait;

Task.Factory.StartNew(() => PerformMigration(legacyTrackerIds)).ContinueWith(_ => this.Cursor = Cursors.Arrow);

カーソルは確かに待機カーソルに変わりますが、タスクが完了しても矢印に戻りません。ContinueWith() メソッドにブレークポイントを設定すると、ヒットします。しかし、カーソルは矢印に戻りません。なんで?

これは私が試していた古い方法でした。カーソルは矢印に戻りましたが、タスクを Wait() したくありません。

this.Cursor = Cursors.Wait;

Task.Factory.StartNew(() => PerformMigration(legacyTrackerIds)).Wait();

this.Cursor = Cursors.Arrow;
4

3 に答える 3

11

カーソルの変更は、UI スレッドで行う必要があります。タスク スケジューラを使用するContinueWithのオーバーロードを使用できます。

var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext(); 

Task.Factory
  .StartNew(() => PerformMigration(legacyTrackerIds))
  .ContinueWith(_ => this.Cursor = Cursors.Arrow, uiScheduler);

またはDispatcher.Invokeメソッドを使用します。

Task.Factory
  .StartNew(() => PerformMigration(legacyTrackerIds))
  .ContinueWith(_ => { Dispatcher.Invoke(() => { this.Cursor = Cursors.Arrow; }); });
于 2012-08-31T14:14:21.070 に答える
2

正しい同期コンテキストを使用する必要があると思います:

this.Cursor = Cursors.Wait; 

var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext()); 

Task.Factory.StartNew(() => PerformMigration(legacyTrackerIds))
            .ContinueWith(_ => this.Cursor = Cursors.Arrow, uiScheduler);
于 2012-08-31T14:14:53.573 に答える
2

問題は、継続を UI スレッドで実行する必要があることです。現在、バックグラウンド スレッドで実行されています。

TaskScheduler.FromCurrentSynchronizationContext()の 2 番目のパラメーターに追加しContinueWithて、UI スレッドで実行します。

于 2012-08-31T14:15:28.877 に答える