Подтвердить что ты не робот

Как написать простой метод async?

Используя последний CTP5 с асинхронными/ожидающими ключевыми словами, я написал код, который, по-видимому, не может скомпилировать:

 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();
        }
    }

Какова причина "Оператор ожидания" может использоваться только в методе или лямбда, отмеченном ошибкой модификатора "async"? " (Я выбрал строку, на которую указывает Visual Studio)

4b9b3361

Ответ 1

Я не знаю, можно ли пометить Main как асинхронный, но вам нужно включить ключевое слово async в объявление любого метода, который использует await. Например:

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

    int result = await myClass.TestAsync ();
}

Ответ 2

await не совпадает с Wait(); выполнение await является значительным повторным написанием этого метода и, в частности, влияет на ожидание того, как этот метод выходит на вызывающий. Вы правы в том, что на самом деле это не так много (caveat: return types), за исключением того, что компилятор разрешает некоторые вещи (как и переключатели типа unsafe, checked и unchecked, если вы думаете об этом) - но подумайте: это действительно имеет значение чрезвычайно в вашем примере. Если Main() выходит (и мы не принимаем никаких других потоков) - вы exe - это тост. Прошло. Более не существует. Добавление async заставляет вас считать, что только потому, что выход метода не означает, что он завершен. Вы действительно не хотите, чтобы Main() вышел, прежде чем вы будете готовы.

В качестве вторичного эффекта этот переключатель также фиксирует, что метод может возвращать только такие вещи, как Task; без переключателя, возможно, у вас возникнет соблазн сделать его асинхронным позже, что может быть значительно нарушением изменений.

Ответ 3

Асинхронный метод может иметь возвращаемый тип void или Task. Если тип возврата не является недействительным, вызывающий может по-прежнему использовать стандартный механизм ожидания, введенный в .Net 4 внутри метода Main entry (который не может быть помечен как async). Вот простой пример:

    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"]);
        }

    }