Быстрый вопрос, я хочу подождать второй перед запуском задачи async без возвращаемого значения.
Правильно ли это сделать?
Task.Delay(1000)
.ContinueWith(t => _mq.Send(message))
.Start();
Что происходит с исключениями?
Быстрый вопрос, я хочу подождать второй перед запуском задачи async без возвращаемого значения.
Правильно ли это сделать?
Task.Delay(1000)
.ContinueWith(t => _mq.Send(message))
.Start();
Что происходит с исключениями?
Прежде всего, Start()
работает только с (очень редким) Task
, созданным с помощью конструктора Task
(например, new Task(() => _mq.Send(message))
). Во всех остальных случаях он выдает исключение, потому что Task
уже запущен или ждет другого Task
.
Теперь, вероятно, лучший способ сделать это - поместить код в отдельный метод async
и использовать await
:
async Task SendWithDelay(Message message)
{
await Task.Delay(1000);
_mq.Send(message);
}
Если вы сделаете это, любое исключение из метода Send()
окажется в возвращаемом Task
.
Если вы не хотите этого делать, использование ContinueWith()
- разумный подход. В этом случае исключение будет в Task
, возвращенном из ContinueWith()
.
Кроме того, в зависимости от типа _mq
, используйте SendAsync()
, если что-то подобное доступно.
Вы можете поймать любое исключение, заданное в Задаче, если вы ждете завершения задачи:
Помните, что ваше исключение, заданное в Задаче, будет внутренним
class Program
{
static void Main(string[] args)
{
try
{
Task task = Task.Delay(1000)
.ContinueWith(t => Program.throwsException());
task.Wait();
}
catch (Exception ex)
{
Console.WriteLine("Exception:" + ex.Message); // Outputs: Exception:One or more errors occurred.
Console.WriteLine("Inner exception:" + ex.InnerException.Message); // Outputs: Exception:thrown
}
Console.ReadKey();
}
static void throwsException()
{
Console.WriteLine("Method started");
throw new Exception("thrown");
}
}
Вы можете наблюдать за любыми исключениями, если вы Wait
для задачи.
Необработанные исключения, которые запускаются с помощью кода пользователя, который выполняется внутри задачи распространяются обратно на соединительный поток, за исключением определенные сценарии, описанные ниже в этом разделе. Исключения распространяются при использовании одного из статических или экземпляров Task.Wait или Task.Wait, и вы обрабатываете их, включив вызов в заявлении try-catch.
Выдержка из Обработка исключений (параллельная библиотека задач)
Будьте осторожны с таймингами. Задачи используют планировщик и не гарантируются, когда вы скажете "идти". Если вы сообщите об этом в Start
, код будет гарантированно не менее 1000 мс, но точно не будет точно 1000 м.