任务ContinueWith()不更新UI线程上的光标

时间:2012-08-31 14:12:52

标签: c# task

我正在开发一个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;

3 个答案:

答案 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线程中运行。