5

我正在开发一个 WPF 应用程序,我只是想在任务运行之前和之后更改光标。我有这个代码:

this.Cursor = Cursors.Wait;

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

光标确实变为等待光标,但在任务完成后它不会变回箭头。如果我在 ContinueWith() 方法中放置一个断点,它就会被命中。但光标不会变回箭头。为什么?

这是我尝试的旧方法。光标变回箭头,但我不想等待()的任务。

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()到第二个参数ContinueWith以使其在 UI 线程中运行。

于 2012-08-31T14:15:28.877 回答