2015-11-02 5 views
0

Перед тем, как использоватьВызова функция асинхронная внутри функции, не асинхронной

protected async void OnResume() { 
    await DoWorkAsync(); // assume exception is appropriately handled 
    await DoOtherWorkAsync(); 
} 

Но теперь я видел другие разработчики используют

protected void OnResume() { 
    SynchronizationContext.Current.Post(async (status) => { 
    await DoWorkAsync(); 
    await DoOtherWorkAsync();}, null); 
} 

ли вторая один правильный и предпочтительный при вызове методов асинхронных внутри не-асинхронном методы? Заранее спасибо.

UPDATE: При использовании 2-й фрагмент кода, вы должны вызвать SynchronizationContext.Current.Post() на UI тему, или вы получите NullReferenceException, причиной SynchronizationContext.Current является недействительным на не-UI Thread. _handler.Post(async() => {// do UI changes}); может быть вызван на тему, отличную от UI, для внесения любых изменений пользовательского интерфейса, при условии, что _handler создан при создании пользовательского интерфейса.

+0

Если Вы можете сделать свой метод асинхр - сделать это, как это общая лаковой в настоящее время. Если это может привести к некоторым неприятностям - вы можете использовать второе решение, так как оно правильно ничего плохого об этом – MajkeloDev

+0

Спасибо @MajkeloDev –

ответ

2

Нет, не используйте SynchronizationContext. Вы уже находитесь в потоке пользовательского интерфейса, поэтому второй вариант действительно не имеет смысла.

Обратите внимание, что обычно следует избегать async void. В этом случае, я бы сказал, что это приемлемо, потому что вы на самом деле лечения OnResume, как будто это обработчик события:

protected async void OnResume() 
{ 
    await DoWorkAsync(); 
} 
+0

Спасибо @Stephen, вторая выбрала исключение null reference для SynchronizationContext.Current, если SynchronizationContext.Current.Post вызывается из не-UIThread. –

+0

@ macio.Jun: Возможно, потому что 'SynchronizationContext.Current' является' null'. –

+0

Да, 'SynchronizationContext.Current' равно null. Я действительно не знаю, почему «SynchronizationContext.Current» имеет значение null, когда он вызывается не-UIThread.MSDN говорит свойство 'Current' ** Получает контекст синхронизации для текущего потока **. –

2

Оба примера выполняют ненужную работу. Лучшая реализация метода будет:

protected void OnResume() 
{ 
    DoWorkAsync(); 
} 

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

Второй фрагмент добавляет два бессмысленных сообщений два текущего контекста синхронизации, один явно и один неявно.

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

+0

Первый пример и ваш код отличаются тем, как обрабатываются исключения из DoWorkAsync. –

+0

@StephenCleary Комментарий в коде указывает, что 'DoWorkAsync' никогда не выбрасывает; он внутренне обрабатывает все свои собственные исключения. – Servy

+0

Привет @Servy, извините за вводящий в заблуждение. На самом деле мне нужно убедиться, что DoOtherWorkAsync() вызывается после завершения DoWorkAsync(). –