我正在开发一个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;
答案 0 :(得分:11)
需要在UI线程上完成游标更改。您可以使用带有任务计划程序的overload of 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; }); });
答案 1 :(得分:2)
我认为您需要使用正确的同步上下文:
this.Cursor = Cursors.Wait;
var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext());
Task.Factory.StartNew(() => PerformMigration(legacyTrackerIds))
.ContinueWith(_ => this.Cursor = Cursors.Arrow, uiScheduler);
答案 2 :(得分:2)
问题是延续需要在UI线程中运行。目前它正在后台线程中完成。
将TaskScheduler.FromCurrentSynchronizationContext()
添加到ContinueWith
的第二个参数,以使其在UI线程中运行。