0

In the article here, Stephen describes that in the outer StartNew (see code snippet below), TaskScheduler.Current is our UI task scheduler. Indeed, the output of the code below seems to indicate that all is executed on the UI thread. However when I try to confirm this, I get a different answer:

private void Button_Click(object sender, RoutedEventArgs e)
{
    var uiTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
    var ui = new TaskFactory(TaskScheduler.FromCurrentSynchronizationContext());
    ui.StartNew(() =>
    {
        Debug.WriteLine("TaskScheduler.Current == UI TaskScheduler: " + (uiTaskScheduler == TaskScheduler.Current));
        Debug.WriteLine("UI on thread " + Environment.CurrentManagedThreadId);
        Task.Factory.StartNew(() =>
        {
            Debug.WriteLine("Background work on thread " + Environment.CurrentManagedThreadId);
        });
    });
}

And the output:

TaskScheduler.Current == UI TaskScheduler: False
UI on thread 1
Background work on thread 1

Why exactly does uiTaskScheduler == TaskScheduler.Current return false?

Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
Marcin
  • 131
  • 6
  • `TaskScheduler.Current` returns an object of type `SynchronizationContext`. Your `uiTaskScheduler` is of type `TaskScheduler`. So these are two different objects of different types and the equality check will always return `false` (even if the scheduler is associated with the context). – Johan Donne May 24 '23 at 05:09
  • See also: https://stackoverflow.com/questions/9580061/what-is-the-conceptual-difference-between-synchronizationcontext-and-taskschedul – Johan Donne May 24 '23 at 05:16
  • TaskScheduler.Current returns a TaskScheduler – Clemens May 24 '23 at 06:53
  • 1
    Clemens' answer explains the problem in this code. Why are you using such code in the first place though? Why do you think you need to verify that scheduling something to run on the UI thread actually runs on the UI thread? Using Task schedulers directly, `Task.Factory` and `StartNew` are rarely used since the introduction of `await` and `Task.Run` in 2012 – Panagiotis Kanavos May 24 '23 at 07:20

1 Answers1

5

Why exactly does uiTaskScheduler == TaskScheduler.Current return false?

The method TaskScheduler.FromCurrentSynchronizationContext() creates a new TaskScheduler instance. Since you are calling it twice, you get two instances - which are not equal although they are associated with the same SynchronizationContext.

Change your code to this:

var uiTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
var ui = new TaskFactory(uiTaskScheduler);
...
Clemens
  • 123,504
  • 12
  • 155
  • 268