Task.Run () не вызывает исключение? - PullRequest
0 голосов
/ 16 ноября 2018

У меня есть следующий код в

private void Button_Click(object sender, EventArgs e)
{
    try
    {
        Task.Run(async () => await Presenter.Search());
    }
    catch (Exception ex)
    {
        LabelMessage.Text = "Error:....";
    }
}

Функция Presenter.Search() может получать исключения в некоторых случаях, и я хочу показать сообщение об ошибке.Тем не менее, исключение не возникает?Я могу видеть это только в отладчике Visual Studio.

Ответы [ 2 ]

0 голосов
/ 16 ноября 2018

Прежде всего, если Presenter.Search уже возвращает Task, вам следует сделать обработчик событий async и просто поместить

await Presenter.Search();

в блок try-catch.

Причина перегрузки Task.Run(Func<Task>) заключается в том, что вы можете принудительно запланировать выполнение уже существующего Task в потоке пула.Этот случай может быть оправдан в очень редких случаях, так как обычно вам следует полагаться на внутреннюю реализацию методов возврата Task.Но если вы знаете, что асинхронный метод не использует потоки (например, просто возвращает Task, который будет завершен при конкретном событии), и вы достаточно уверены в том, что принудите выполнение в потоке пула, вы можете сделать это следующим образом.путь.Но и в этом случае вам следует дождаться внешней задачи;в противном случае вызов будет «забыл и забыл», и вы ничего не поймете:

await Task.Run(() => Presenter.Search());

Обратите внимание, что я пропустил внутренний async-await:

await Task.Run(async () => await Presenter.Search());

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

TL; DR: Без знания каких-либо дополнительных подробностей await Presenter.Search(); представляется лучшим решением, но также await Task.Run(() => Presenter.Search()); может быть оправдано, если вы знаете, что делаете.

0 голосов
/ 16 ноября 2018

На самом деле это должно быть написано так:

private async void Button_Click(object sender, EventArgs e)
{
    try
    {
        await Presenter.Search();
    }
    catch (Exception ex)
    {
        LabelMessage.Text = "Error:....";
    }
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...