rhughes
rhughes

Reputation: 9583

Confusion over .NET 4 Async

I am using the Microsoft.Bcl.Async nuget package to use Async/Await (My target is .NET 4, rather than 4.5)

I am new to Async/Await. My problem is described in the following code sample. Why is the highlighted line not called?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AsyncTest
{
class Program
{
    static void Main(string[] args)
    {
        Run();

        Console.WriteLine("Got the value");

        Console.ReadKey();
    }

    public static async void Run()
    {
        Console.WriteLine("Testing Async...");

        var val = await AsyncMethod();

        // HIGHLIGHTED LINE. WHY IS THIS LINE NOT CALLED?
        Console.WriteLine("And the value is... {0}", val);
    }

    public static Task<long> AsyncMethod()
    {
        long myVal = 1;

        for (long l = 0; l < 100000; l++)
        {
            myVal++;
            Console.WriteLine("l = {0}", l);
        }

        return new Task<long>(() => myVal);
    }
}
}

Upvotes: 3

Views: 1162

Answers (2)

Lars H
Lars H

Reputation: 57

You shouldn't call it "AsyncMethod" because it have no async elements.

The method uses a Task that will run in a separate thread from Current thread.

Upvotes: -1

Marc Gravell
Marc Gravell

Reputation: 1064134

The line:

Console.WriteLine("And the value is... {0}", val);

is converted (by the compiler) into a continuation; it will get invoked (with the value etc) only when the task that is being "awaited" completes. The problem is: you create a task, but you haven't started it: so it will never complete.

If you start the task you create at the bottom, it will eventually complete. Also, normally you would put the "doing" work inside the Task - not outside it:

    public static Task<long> AsyncMethod()
    {
        var task = new Task<long>(() =>
        {
            long myVal = 1;

            for (long l = 0; l < 100000; l++)
            {
                myVal++;
                Console.WriteLine("l = {0}", l);
            }
            return myVal;
        });
        task.Start();
        return task;
    }

Also note that Got the value gets printed out long before the And the value is... - that is because the continuation happens on a worker thread; the Run method returns control to the caller (Main) at the first await.

Upvotes: 5

Related Questions