kazinix
kazinix

Reputation: 30093

async / await and Task / Wait in C# the same?

I learned to use Task easily than async/await. Now, I'm trying to use Task to learn async/await.

    static void Main(string[] args)
    {
        Console.ReadKey(true);
        //Magic1(); 
        Magic2();
        Console.WriteLine("{0}", DateTime.Now.ToString());
        Console.ReadKey(true);
    }

    static async void Magic1()
    {
        var taskA = GetDataAsync();
        var taskB = GetDataAsync();
        var taskC = GetDataAsync();

        Console.WriteLine("a: " + await taskA);
        Console.WriteLine("b: " + await taskB);
        Console.WriteLine("c: " + await taskC);
    }

    static Task Magic2()
    {
        return Task.Run(() =>
        {
            var taskA = GetDataAsync();
            var taskB = GetDataAsync();
            var taskC = GetDataAsync();

            Task.WaitAll(new Task[] { taskA, taskB, taskC });

            Console.WriteLine("a: " + taskA.Result);
            Console.WriteLine("b: " + taskB.Result);
            Console.WriteLine("c: " + taskC.Result);
        });
    }

    static Task<string> GetDataAsync()
    {
        return Task.Run(() => 
        {
            var startTime = DateTime.Now;
            for (var i = 0; i < 1000000000; i++)
            {
            }
            var endTime = DateTime.Now;
            return startTime.ToString() + " to " + endTime.ToString() + " is " + (endTime - startTime).ToString();
        });
    }

I created two methods that appears to do the same thing, my questions are:

1) is Magic1 and Magic2 the same under the hood?

2) if they are not the same, can I convert Magic1 to a method that does the same thing without using async and await keywords?

Upvotes: 0

Views: 268

Answers (2)

Stephen Cleary
Stephen Cleary

Reputation: 456417

Now, I'm trying to use my knowledge in Task to learn async/await.

I really recommend you not do this. Although task-based parallelism (.NET 4.0) and the task-based asynchronous pattern (async/await) use the same type (Task), they are completely different. They solve different problems and have a different way of working.

Instead, I suggest you pretend that you know nothing about the Task type and start with my async intro. At the end of my async intro are several followup resources, including the MSDN docs which are quite good for this feature.

If you're really familiar with continuations, you can (mostly) think of await as meaning "rewrite the rest of this method as a continuation and schedule it using the current SynchronizationContext or TaskScheduler". But even that is only an approximation; there are plenty of edge cases. It is not at all the same as doing a Task.Wait[All] within a Task.Run.

Upvotes: 4

Craig Gidney
Craig Gidney

Reputation: 18276

Differences between the two methods:

  • Where their code runs. Magic2 will run on the threadpool instead of in the caller's synchronization context, because you (unnecessarily) used Task.Run. If you were writing UI code, this could cause Magic2 to fail.
  • Blocking. Magic1 blocks the caller until it is done. This is generally a mistake when writing async code. Magic2 won't block the caller, even if you remove the Task.Run.
  • Incremental work. If taskB takes significantly longer to complete, that won't delay Magic2 from printing the result of taskA. Magic1 waits for all three tasks to finish, so it won't print taskA until after taskB finished.

Upvotes: 1

Related Questions