Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write simple async method?

Tags:

c#

async-ctp

Using latest CTP5 with async/await keywords, I wrote some code, which apparently cannot compile:

 class Program
    {
        public class MyClass
        {
            async public Task<int> Test()
            {
                var result = await TaskEx.Run(() =>
                    {
                        Thread.Sleep(3000);
                        return 3;
                    });
                return result;
            }
        }

        static void Main(string[] args)
        {
            var myClass = new MyClass();

            //The 'await' operator can only be used in a method or lambda marked with the 'async' modifier error ??!!
            int result = await myClass.Test();

            Console.ReadLine();
        }
    }

What is th reason of "The 'await' operator can only be used in a method or lambda marked with the 'async' modifier error?" (I've selected the line which Visual Studio point me to)

like image 811
ghord Avatar asked Jul 21 '11 07:07

ghord


People also ask

How do you write async method?

The first step is to add the async keyword to the method. It appears in the method signature in the same way that the static keyword does. Then, we need to wait for the download using the await keyword. In terms of C# syntax, await acts as a unary operator, like the !

How is async method implemented?

As MSDN states: You can use await Task. Yield(); in an asynchronous method to force the method to complete asynchronously. Insert it at beginning of your method and it will then return immediately to the caller and complete the rest of the method on another thread.

What are async methods?

An async method runs synchronously until it reaches its first await expression, at which point the method is suspended until the awaited task is complete. In the meantime, control returns to the caller of the method, as the example in the next section shows.


3 Answers

I don't know if you can mark Main as async, but you need to include the async keyword in the declaration of any method that uses await. For example:

public async void DoStuffAsync ()
{
    var myClass = new MyClass ();

    int result = await myClass.TestAsync ();
}
like image 182
Bodrick Avatar answered Sep 29 '22 19:09

Bodrick


await is not the same as Wait(); doing an await is a significant re-writing of that method, and in particular affects the expectation of how that method exits to the caller. You are right in that it doesn't actually do much (caveat: return types) except tell the compiler to enable some things (as do switches like unsafe, checked and unchecked if you think about it) - but consider: this actually matters hugely in your example. If Main() exits (and we assume no other threads) - you exe is toast. Gone. No longer exists. Adding async makes you consider that just because the method exits doesn't mean it has finished. You really don't want Main() exiting before you are ready.

As a secondary effect, this switch also formalises that the method can only return things like Task; without the switch, you might be tempted to make it async later, which could be a significantly breaking change.

like image 43
Marc Gravell Avatar answered Sep 29 '22 18:09

Marc Gravell


An async method can have a return type of void or Task. If the return type is not void the caller can still use the standard Wait mechanism introduced in .Net 4 inside the Main entry method (which can not be marked async). Here's a simple example:

    static void Main(string[] args)
    {
        string address = "http://api.worldbank.org/countries?format=json";
        Task t = LoadJsonAsync(address);
        // do other work while loading
        t.Wait();

        Console.WriteLine("Hit ENTER to exit...");
        Console.ReadLine();
    }

    private async static Task LoadJsonAsync(string address)
    {
        HttpClient client = new HttpClient();

        HttpResponseMessage response = await client.GetAsync(address);

        // Check that response was successful or throw exception
        response.EnsureSuccessStatusCode();

        // Read response asynchronously as JsonValue and write out top facts for each country
        JsonArray readTask = await response.Content.ReadAsAsync<JsonArray>();
        Console.WriteLine("First 50 countries listed by The World Bank...");
        foreach (var country in readTask[1])
        {
            Console.WriteLine("   {0}, Capital: {1}",
                country.Value["name"],
                country.Value["capitalCity"]);
        }

    }
like image 33
Andrew Scoppa Avatar answered Sep 29 '22 17:09

Andrew Scoppa