Home > Net >  Can a Task<TResult> be used to start and store a async method without an explicit Task method
Can a Task<TResult> be used to start and store a async method without an explicit Task method

Time:08-02

When I look at this example from the MS docs, the call a Task without using Run or StartNew like this,

Coffee cup = PourCoffee();
Console.WriteLine("Coffee is ready");

Task<Egg> eggsTask = FryEggsAsync(2);
Task<Bacon> baconTask = FryBaconAsync(3);
Task<Toast> toastTask = ToastBreadAsync(2);

Toast toast = await toastTask;
ApplyButter(toast);
ApplyJam(toast);
Console.WriteLine("Toast is ready");
Juice oj = PourOJ();
Console.WriteLine("Oj is ready");

Egg eggs = await eggsTask;
Console.WriteLine("Eggs are ready");
Bacon bacon = await baconTask;
Console.WriteLine("Bacon is ready");

Console.WriteLine("Breakfast is ready!");

But all the documentation I have found looks like you have to call Run, StartNew, or something else.

The article that has the Breakfast example says,

You start a task and hold on to the Task object that represents the work. You'll await each task before working with its result.

Why don't they have to call Run or StartNew or some other method?

Here is the complete working part I have. It runs, and I understand what it accomplishes, but I don't know why they don't use Run (()=>, etc.

 namespace AsyncBreakfast
    {
        // These classes are intentionally empty for the purpose of this example.
        // They are simply marker classes for the purpose of demonstration,
        // contain no properties, and serve no other purpose.
        internal class Bacon { }
        internal class Coffee { }
        internal class Egg { }
        internal class Juice { }
        internal class Toast { }

        class Program
        {
            static async Task Main(string[] args)
            {
                Coffee cup = PourCoffee();
                Console.WriteLine("Coffee is ready");

                Task<Egg> eggsTask = FryEggsAsync(2);
                Task<Bacon> baconTask = FryBaconAsync(3);
                Task<Toast> toastTask = ToastBreadAsync(2);

                Toast toast = await toastTask;
                ApplyButter(toast);
                ApplyJam(toast);
                Console.WriteLine("Toast is ready");
                Juice oj = PourOJ();
                Console.WriteLine("Oj is ready");

                Egg eggs = await eggsTask;
                Console.WriteLine("Eggs are ready");
                Bacon bacon = await baconTask;
                Console.WriteLine("Bacon is ready");

                Console.WriteLine("Breakfast is ready!");

            }

        static async Task<Toast> MakeToastWithButterAndJamAsync(int number)
        {
            var toast = await ToastBreadAsync(number);
            ApplyButter(toast);
            ApplyJam(toast);

            return toast;
        }

        private static Juice PourOJ()
        {
            Console.WriteLine("Pouring orange juice");
            return new Juice();
        }

        private static void ApplyJam(Toast toast) =>
            Console.WriteLine("Putting jam on the toast");

        private static void ApplyButter(Toast toast) =>
            Console.WriteLine("Putting butter on the toast");

        private static async Task<Toast> ToastBreadAsync(int slices)
        {
            for (int slice = 0; slice < slices; slice  )
            {
                Console.WriteLine("Putting a slice of bread in the toaster");
            }
            Console.WriteLine("Start toasting...");
            await Task.Delay(3000);
            Console.WriteLine("Remove toast from toaster");

            return new Toast();
        }

        private static async Task<Bacon> FryBaconAsync(int slices)
        {
            Console.WriteLine($"putting {slices} slices of bacon in the pan");
            Console.WriteLine("cooking first side of bacon...");
            await Task.Delay(3000);
            for (int slice = 0; slice < slices; slice  )
            {
                Console.WriteLine("flipping a slice of bacon");
            }
            Console.WriteLine("cooking the second side of bacon...");
            await Task.Delay(3000);
            Console.WriteLine("Put bacon on plate");

            return new Bacon();
        }

        private static async Task<Egg> FryEggsAsync(int howMany)
        {
            Console.WriteLine("Warming the egg pan...");
            await Task.Delay(3000);
            Console.WriteLine($"cracking {howMany} eggs");
            Console.WriteLine("cooking the eggs ...");
            await Task.Delay(3000);
            Console.WriteLine("Put eggs on plate");

            return new Egg();
        }

        private static Coffee PourCoffee()
        {
            Console.WriteLine("Pouring coffee");
            return new Coffee();
        }
    }

CodePudding user response:

Why don't they have to call Run or StartNew or some other method?

By convention, Tasks are returned "hot"; i.e., already in progress.

Task.Run will schedule the asynchronous method onto a thread pool thread. Just calling the method directly will begin executing the asynchronous method on the current thread (as I explain on my blog).

Regarding the "most common" phrase: that was likely true when it was written over 12 years ago. I'd say it's certainly not true today; the most common way to get tasks these days is by calling an async method.

  • Related