1
using System;
using System.Threading;
using System.Threading.Tasks;

namespace application
{
    public class Files
    {
        public static Task<string> runTask()
        {
            return Task.Run(() =>
            {
                Thread.Sleep(2000);
                return "Hello World!";
            });
        }

        public static async void Hello()
        {   
            string result = await runTask();
            Console.WriteLine(result);
            Console.WriteLine("Execution Ended!");
        }

        public static void Main(string[] args)
        {
            Hello();
            Console.WriteLine("The Async Code Is Running Above!");
        }

    };
};

The above C# code just prints "The Async Code Is Running Above!" and nothing happens after that.

How can I make this print things in following order (And where I'm going wrong):

"The Async Code Is Running Above!" "Hello World!" "Execution Ended!"

Thankyou!

Hitesh Kumar Saini
  • 336
  • 1
  • 5
  • 14
  • Add console.readline() as last line in main method. Your main method doesn't wait for the for the task to complete. Moreover void method u can not await also. Avoid using void async methods. – neelesh bodgal Jun 07 '20 at 13:17
  • Is the title supposed to say that the console "exits" instead of "exists"? – Wyck Jun 07 '20 at 13:54
  • Corrected! :-P didn't notice that... Sorry for inconvenience. – Hitesh Kumar Saini Jun 07 '20 at 13:59
  • But you're **not** using `await`. `Hello` is an `async void` method aka "fire and forget". If you want to wait until this one completes before continuing, you **will** have to make it non-void, and you **will** have to await it. Since you don't, the program will run it and start the task machinery, and then just return back to Main and trundle on, writing one additional line to the console before returning and thus exiting the application. – Lasse V. Karlsen Jun 12 '20 at 15:29

2 Answers2

5

There are a two main points in your question. First, don't use Thread.Sleep inside asynchronous methods, use Task.Delay instead. Second, you can make Main method async as well and return a Task to get an expected behavior (it's possible starting from C# 7.1)

public static Task<string> runTask()
{
    return Task.Run(async () =>
    {
        await Task.Delay(2000);
        return "Hello World!";
    });
}

public static async Task Hello()
{
    string result = await runTask();
    Console.WriteLine(result);
    Console.WriteLine("Execution Ended!");
}

static async Task Main()
{
    await Hello();
    Console.WriteLine("The Async Code Is Running Above!");
}
Pavel Anikhouski
  • 21,776
  • 12
  • 51
  • 66
2

Avoid using void async methods, try returning tasks always. Check this post for more details async-await-when-to-return-a-task-vs-void

class Files
{
    static void Main(string[] args)
    {
        Task t = Hello();
        Console.WriteLine("The Async Code Is Running Above!");

        //Wait for the task to complete
        //Dont use this code in UI applications which will cause blocking
        t.Wait();

        //keep the application open
        Console.ReadLine();
    }

    public static Task<string> runTask()
    {
        return Task.Run(async () =>
       {
           await Task.Delay(2000);
           return "Hello World!";
       });
    }

    public static async Task Hello()
    {
        string result = await runTask();
        Console.WriteLine(result);
        Console.WriteLine("Execution Ended!");
    }

}
neelesh bodgal
  • 632
  • 5
  • 14
  • 4
    As of [C# 7.1](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-7-1#async-main) the Main method can itself be `async` - `public static async Task Main(string[] args) { }` – stuartd Jun 07 '20 at 14:03
  • 1
    @HiteshKumarSaini if you are using c#7.1 then u can replace the line t.Wait(); by await t and make the main method async. for details check out stuartd link. – neelesh bodgal Jun 07 '20 at 14:06