2014-12-03 3 views
4

Предположим, у меня есть метод, который имеет возвращаемый тип void и что мне нужно await по операции в этом методе.Зачем использовать метод void async для ожидания?

public void someOperation() 
{ 
    //dostuff 
    var res = await someOtherOperation(); 
    //do some other stuff that needs res. 
} 

Когда я попытался скомпилировать этот код, я получил ошибку говоря someOperation должен объявить async. Я не понимаю, почему. Я понимаю, почему это было бы, если бы метод имел возвращаемое значение, но не здесь, когда он равен void. или даже в том случае, когда ожидающая операция не влияет на возвращаемое значение метода.
Это предложение уже задан как часть вопроса this, но я не нашел ответ, который я искал. This guy просто упоминает:

Ключевое слово async позволяет использовать ключевое слово ожидания. Поэтому любой метод, использующий ожидание , должен быть помечен как асинхронный.

  • Прежде всего, я не уверен, что это означает, что ключевое слово async позволяет await ключевое слово.
  • И, во-вторых, повторив мой вопрос, я не уверен, зачем это ?
+2

1) Вы не можете использовать оператор 'await' в методе, который не объявлен' async'. Таким образом, он * допускает * оператор. 2) Я не уверен, что понимаю, в чем ваш вопрос: «Почему это требуется?» Это необходимо, потому что так работает работа. в чем именно проблема?: –

+0

Я имею в виду, он должен быть там, чтобы соответствовать существующему дизайну? Дизайнеры не хотели делать исключение в этом случае? Потому что по тому, как я смотрю на него, это не требуется. Метод будет работать отлично, если вызывающий абонент не должен знать, что он «async». – atoMerz

ответ

11

Асинхронные методы должны быть маркированы async. Ключевые слова async и await сочетаются вместе, в первую очередь, по соображениям обратной совместимости; await был действительным идентификатором (а не ключевым словом), поэтому, когда он был добавлен на язык, они также добавили ключевое слово async.

С другой стороны, они могли пошли с несколько словом ключевым словом для await, таких как await for. Однако команда разработчиков языка решила пойти с сопряжением, поскольку она четко и явно маркирует все методы async - для компиляторов и людей проще разбираться.

У меня есть blog post on the subject, со ссылками на Eric Lippert's definitive blog post, а также обсуждения в blog comments, Channel9 forums, MSDN forums, и конечно right here on Stack Overflow.

Обратите внимание, что естественный тип возвращаемого из async метода без значения результата является Task, не void. void - неестественный тип возврата для методов async. Таким образом, ваша реакция по умолчанию при виде «оператора ждет должен быть в пределах метода асинхронного» ошибка должна быть, чтобы отметить его asyncи изменить тип возвращаемого из void в Task:

public async Task someOperationAsync() 
{ 
    //dostuff 
    var res = await someOtherOperationAsync(); 
    //do some other stuff that needs res. 
} 

Это следует одна из лучших практик в моем MSDN article on the subject: избегайте async void. async void был разрешен разработчиками языка для обработчиков событий (или код логически обработчик события, например ICommand.Execute); любое другое использование вызовет проблемы.

11

Я не понимаю, почему.

Потому что вам нужно сообщить компилятору, что вы пытаетесь написать метод async. Это именно то, что означает документ, который вы цитируете.

Компилятор может сделать вывод, что из включает ли ваш метод любые await выражения - но это означало бы, вы могли бы прокомментировать одну линию способа и поведение всего метода будет радикально изменения. (Подумайте об обработке исключений, например ...)

Он также улучшает читаемость - это означает, что кто-либо читает ваш код знает Это метод асинхронного действия с самого начала.

Так в основном, ответы:

  • Вам нужно, потому что спецификация языка требует от вас. Компилятор реализует спецификацию языка.
  • Спецификация языка требует от вас, потому что это уменьшает элемент неожиданности.
+0

Джон, есть ли дубликат этого? Если нет, то это может стать каноническим «зачем мне задавать вопрос« async »? –

+0

@JohnSaunders: Не знаю, что я знаю. Там может быть, но я не знаю об этом прямо сейчас :) –

+0

@JohnSaunders Каноническая ссылка для этого, на мой взгляд, [блог Эрика] (http://blogs.msdn.com/b/ericlippert/ архив/2010/11/11/whither-async.aspx) по этому вопросу. Он включает в себя как более глубокое изложение пунктов Йон, приведенных здесь, так и несколько других, например, избегая нарушения изменений (что, если у кого-то был метод, называемый 'await' pre-5.0?). – Servy

0

Потому что они должны работать в паре в C#. Это правило.

Ключевое слово «async» позволяет использовать ключевое слово «ожидание» в этом методе и изменяет способ обработки результатов метода. Это все ключевое слово async! Он не запускает этот метод в потоке пула потоков или не делает другого волшебства. Ключевое слово async включает только ключевое слово ожидания (и управляет результатами метода).

Смежные вопросы