Channing
Channing

Reputation: 5

Async function confusion for parallelism

I write the sample code based on the tutorial.

I think when TestAsync Task runs, the "Logic A" will be printed and then with the "await" keyword "Logic C" be printed.

But it actually runs just like a synchronized way, print "Logic C" then "Logic A"

class Program
{
    static void Main(string[] args)
    {
        TestAll();
    }

    static async void TestAll()
    {
        var y = TestAsync();

        // I want to do other jobs before task y finish
        Console.WriteLine("Logic A");

        int value = await y;
        Console.ReadLine();
    }

    static Task<int> TestAsync()
    {
        for (int i = 0; i < 20000; i++)
            ;
        Console.WriteLine("Logic C");
        return Task.FromResult(0);
    }
}

But why print Logic C then Logic A ?

enter image description here

Thanks the answers, then another question: I expect "Logic B" --> "Logic A" --> "Logic C" --> "1"

But it actually only prints "Logic B" --> "Logic A" and finished.

class Program
{
    static void Main(string[] args)
    {
        TestAll();
    }

    static async void TestAll()
    {
        var y = TestAsync();

        // I want to do other jobs before task y finish
        Console.WriteLine("Logic A");

        // delete this line will be correct, but I don't know why
        int value = await y;
        Console.WriteLine(value);
        Console.ReadLine();
    }

    static async Task<int> TestAsync()
    {
        Console.WriteLine("Logic B");
        await Task.Delay(100);
        Console.WriteLine("Logic C");
        return 1;
    }
}

Upvotes: 0

Views: 49

Answers (1)

Tomas Chabada
Tomas Chabada

Reputation: 3019

As you stated, the output indicates the synchronous processing, because it actually is a synchronous processing.

Defining Task does not mean asynchronous processing. There is no new Task creation, you only wrapped code to Task, but you did not create a new one.
If you want to test async processing, you should modify your method:

private Task<int> TestAsync()
{
    return Task.Run(() =>
    {
        for (int i = 0; i < 20000; i++)
            ;
        Console.WriteLine("Logic C");
        return Task.FromResult(0);
    });
}

To answer your another question:

You don't have desired output because your Main method is not waiting for asynchronous operation to finish. So as a execution in method TestAll goes to int value = await y; the main method will continue and will finish gracefully.

Update your Main method to wait for async task and you will get desired output:

static void Main(string[] args)
{
   TestAll().Wait();
}

But look at synchronously waiting on asynchronous task problem. It is related to context threads (UI thread, ASP context thread,...) so it should be safe with Console app, but always good to know what is behind.

Upvotes: 1

Related Questions