Подтвердить что ты не робот

Задержка затем выполняет задачу

Быстрый вопрос, я хочу подождать второй перед запуском задачи async без возвращаемого значения.
Правильно ли это сделать?

Task.Delay(1000)
    .ContinueWith(t => _mq.Send(message))
    .Start();

Что происходит с исключениями?

4b9b3361

Ответ 1

Прежде всего, 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(), если что-то подобное доступно.

Ответ 2

Вы можете поймать любое исключение, заданное в Задаче, если вы ждете завершения задачи:

Помните, что ваше исключение, заданное в Задаче, будет внутренним

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");
    }
}

Ответ 3

Вы можете наблюдать за любыми исключениями, если вы Wait для задачи.

Необработанные исключения, которые запускаются с помощью кода пользователя, который выполняется внутри задачи распространяются обратно на соединительный поток, за исключением определенные сценарии, описанные ниже в этом разделе. Исключения распространяются при использовании одного из статических или экземпляров Task.Wait или Task.Wait, и вы обрабатываете их, включив вызов в заявлении try-catch.

Выдержка из Обработка исключений (параллельная библиотека задач)

Будьте осторожны с таймингами. Задачи используют планировщик и не гарантируются, когда вы скажете "идти". Если вы сообщите об этом в Start, код будет гарантированно не менее 1000 мс, но точно не будет точно 1000 м.