Why is TaskScheduler.Current the default TaskScheduler?

后端 未结 5 692
野趣味
野趣味 2020-11-30 20:25

The Task Parallel Library is great and I\'ve used it a lot in the past months. However, there\'s something really bothering me: the fact that TaskScheduler.Current is the de

5条回答
  •  抹茶落季
    2020-11-30 21:02

    I've just spent hours trying to debug a weird issue where my task was scheduled on the UI thread, even though I didn't specify it to. It turned out the problem was exactly what your sample code demonstrated: A task continuation was scheduled on the UI thread, and somewhere in that continuation, a new task was started which then got scheduled on the UI thread, because the currently executing task had a specific TaskScheduler set.

    Luckily, it's all code I own, so I can fix it by making sure my code specify TaskScheduler.Default when starting new tasks, but if you aren't so lucky, my suggestion would be to use Dispatcher.BeginInvoke instead of using the UI scheduler.

    So, instead of:

    var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
    var task = Task.Factory.StartNew(() => Thread.Sleep(5000));
    task.ContinueWith((t) => UpdateUI(), uiScheduler);
    

    Try:

    var uiDispatcher = Dispatcher.CurrentDispatcher;
    var task = Task.Factory.StartNew(() => Thread.Sleep(5000));
    task.ContinueWith((t) => uiDispatcher.BeginInvoke(new Action(() => UpdateUI())));
    

    It's a bit less readable though.

提交回复
热议问题