Rowan Smith
Rowan Smith

Reputation: 2180

Difference in using Task.Delay or Task.Run to start a task

Both of the below result in the for loop running on it's own thread. Neither of them are marked complete until the for loop completes.

class Program
{
    static async Task SomethingAsync()
    {
        await Task.Run(() =>
            {
                for (int i = 0; i < 100; i++)
                    Console.WriteLine("s11{0}  {1}", i, Thread.CurrentThread.ManagedThreadId);
            }
        );
    }
    static async Task SomethingAsync2()
    {
        await Task.Delay(1);
        for (int i = 0; i < 100; i++)
            Console.WriteLine("s22{0}  {1}", i, Thread.CurrentThread.ManagedThreadId);
    }
    static void Main(string[] args)
    {
        var t1 = SomethingAsync();
        var t2 = SomethingAsync2();

        for (int i = 0; i < 300; i++)
            Console.WriteLine("m{0}  {1}  {2}  {3}", i, Thread.CurrentThread.ManagedThreadId,t1.IsCompleted,t2.IsCompleted);
    }
}

Is there any functional difference? (Apart from the obvious delay)

In the case of SomethingAsync2() Task.Delay was something I found by mistake. Can the await call any method that returns a GetAwaiter?

Upvotes: 2

Views: 232

Answers (1)

Paulo Morgado
Paulo Morgado

Reputation: 14856

Because a console application doesn't have a synchronization context, the continuations will always be scheduled to a thread pool thread.

However, if a synchronization context is present (like in Windows Forms, WPF, UWP, etc.), continuations will be posted to the captured synchronization context.

See the ConfigureAwait FAQ.

By the way, Task.Yield() does what you're trying to do with Task.Delay(1) without involving a timer.

Upvotes: 2

Related Questions