2017-01-16 2 views
3

Я обычно программирую веб-серверы, и сначала я думал, что должна быть непрерывная цепочка методов, возвращающих задачу, поэтому заполнение стека может запрашивать базу данных, если это будет сделано.Как C# обрабатывать async void

Недавно я увидел МОФ код, который делает что-то вроде этого:

public async void Execute(object parameter) 
    { 
     await ExecuteAsync(parameter); 
    } 

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

ответ

6

Async void предназначен для сопоставления обработчика событий/делегатов. что Execute является обратным вызовом события, вероятно, с DelegateCommand или аналогичным.

Как он работает, он относится к нему точно так же, как если бы у вас была функция, которая возвращала Task, но вызывающий не вызывал await на эту возвращенную задачу.

На ASP.NET вы, вероятно, никогда не использовать асинхронную пустоту и вместо того, чтобы быть с помощью контроллеров, которые предоставляют методы, которые возвращают Task<ActionResult>, используйте HostingEnviorment.QueueBackgroundWorkItem, или с помощью функции, завернутые в в ситуациях, в Page.RegisterAsyncTask, где бы вы использовали async void в обычном программировании на рабочем столе.

public void Page_Load(object sender, EventArgs e) 
{ 
    RegisterAsyncTask(new PageAsyncTask(LoadSomeData)); 
} 
+0

Что происходит, когда я не жду задания? – user2029276

+1

@ user2029276 Подсистема asp.net не знает о задаче и может разорвать домен приложения для веб-сайта до того, как функция завершила выполнение, вызвав работу, которую вы сказали, что функция должна быть потеряна и никогда не завершена. Причина, по которой вы можете избежать этого в WPF, - это то, что приложение AppDomain не будет случайно разорвано, пока пользователь использует программу, если в программе работает AppDomain. Неактивный пользователь на сайте asp.net мог бы отключить AppDomain и даже не заметить его. –

7

Я объясняю, как работают async void методы - и почему их следует избегать - в моей Best Practices in Asynchronous Programming статье.

async void имеет такую ​​же семантику, что и async Task, за исключением исключений. Метод async void будет записывать текущий SynchronizationContext в начале метода, и любые исключения из этого метода будут захвачены и подняты непосредственно в этом захваченном контексте. В наиболее распространенных сценариях это приведет к исключению на уровне приложения, обычно к сбою. Некоторые люди называют async void методами «огонь и забыть», но из-за их исключительного поведения я предпочитаю «огонь и крах». :)

«Избегайте асинхронной пустоты» является общим руководством с одним заметным исключением: обработчики событий (или элементы, которые являются логически обработчиками событий, например ICommand.Execute).

Как это работает? Как это перевести на aspnet?

Он работает точно так же, как любой другой async метод. Основное различие в платформе заключается в том, что в UI-потоке не требуется знать, когда метод async завершен. ASP.NET должен знать, что он знает, когда отправить запрос, но пользовательский интерфейс не должен знать, когда метод async завершен. Так работает async void. Его все же лучше избегать, потому что , вызывающий код обычно делает должен знать, когда он будет завершен.

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