Почему компилятор не позволяет использовать ожидание внутри блока catch - программирование
Подтвердить что ты не робот

Почему компилятор не позволяет использовать ожидание внутри блока catch

Скажем, у меня есть асинхронный метод:

public async Task Do()
{
    await Task.Delay(1000);
}

Другой метод пытается вызвать метод Do внутри catch block

public async Task DoMore()
{
    try
    {
    }
    catch (Exception)
    {
        await Do(); //compiled error.
    }
}

Но таким образом, компилятор не позволяет использовать await внутри catch, есть ли какая-то причина за сценой, почему мы не могли использовать его таким образом?

4b9b3361

Ответ 1

Обновление

Это будет поддерживаться на С# 6. Оказалось, что это было принципиально невозможно, и команда разработала, как это сделать, не сойдя с ума в реализации:)

Оригинальный ответ

Я сильно подозреваю, что это аргумент который предотвращает использование yield return в блоке catch.

В частности:

Во-первых, у нас все еще есть проблема, что незаконно "переходить" в середину обработчика защищенной зоны. Единственный способ войти в блок catch - это "нелокальное переключение", которое перехватывает исключение. Поэтому, как только вы вышли из блока catch, в следующий раз, когда был вызван MoveNext, wed не сможет вернуться в блок catch, где мы остановились.

Во-вторых, исключение, которое было выбрано и пойманное, является неотъемлемой частью выполнения блока catch, потому что его можно перебросить с помощью синтаксиса "пустой бросок". У нас нет способа сохранить это состояние через вызовы MoveNext.

Замените "yield" на "wait" там, и я думаю, что вы получите ответ.

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