Является ли выполнение async Task и async void одинаковым - PullRequest
0 голосов
/ 10 октября 2019

В примерах кода используется Xamarin Android.

Я расширяю IntentService. У него мало методов жизненного цикла. В частности, void OnHandleIntent(Intent intent), где вы выполняете реальную работу, и void OnDestroy(), который вызывается системой, когда она видит, что служба закончила работу, и пришло время ее уничтожить. Для IntentService конец его жизни - это когда OnHandleIntent возвращается.

Будучи методом, подобным событию, можно использовать async void OnHandleIntent. Рассмотрим следующий код

protected override async void OnHandleIntent(Intent intent)
{
    Debug.Out("OnHandleIntent Start");
    await Task.Run(async () => await Task.Delay(1000));
    Debug.Out("OnHandleIntent End");
}

protected override void OnDestroy(Intent intent)
{
    base.OnDestroy();
    Debug.Out("OnDestroy");
}

Вывод:

Debug.Out("OnHandleIntent Start");
Debug.Out("OnDestroy");
Debug.Out("OnHandleIntent End");

В то же время следующий (блокирующий) код работает как положено

protected override void OnHandleIntent(Intent intent)
{
    Debug.Out("OnHandleIntent Start");
    Task.Run(async () => await Task.Delay(1000)).Wait();
    Debug.Out("OnHandleIntent End");
}

protected override void OnDestroy(Intent intent)
{
    base.OnDestroy();
    Debug.Out("OnDestroy");
}

Вывод:

Debug.Out("OnHandleIntent Start");
Debug.Out("OnHandleIntent End");
Debug.Out("OnDestroy");

Вопрос - почему это происходит?

1 Ответ

1 голос
/ 10 октября 2019

async void методы не могут ожидаться вызывающей стороной (потому что никакая задача не возвращается для ожидания).

Первая реализация вернется до выполнения Delay;это будет выполнено как пожар и забыл операцию.


Кстати.

await Task.Run(async () => await Task.Delay(1000))

может быть

await Task.Delay(1000))
...