延迟然后执行任务



快速问题,我想启动没有返回值的异步任务之前等待一秒钟.
这是正确的方法吗?

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() 是一种合理的方法。在这种情况下,异常将出现在从 ContinueWith() 返回的Task中。

另外,根据 _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");
    }
}

我想要一些代码并行运行,该代码在服务总线上发布两条消息,消息之间有延迟。这是我的代码:

var _ = _serviceBus.PublishAsync(message1)
        .ContinueWith(async f =>
        {
            if (f.IsFaulted)
            {
                logger.LogError(f.Exception, $"Exception was thrown while publishing message {f.Id}");                
            }
            await Task.Delay(5000);
            var _ = _serviceBus.PublishAsync(message2)
            .ContinueWith(f =>
            {
                logger.LogError(f.Exception, $"Exception was thrown while publishing message {f.Id}");
            }, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.Default);
        }, TaskScheduler.Default);

如果您Wait该任务,您将能够观察到任何异常。

正在运行的用户代码引发的未经处理的异常 任务内部将传播回连接线程,但 本主题后面将介绍的某些方案。异常 在使用静态或实例任务之一时传播。等待或 Task.Wait 方法,您可以通过封闭调用来处理它们 在尝试捕获语句中。

摘自异常处理(任务并行库)

注意时间。任务使用计划程序,并且不保证在您说"开始"时启动。您的代码在告诉它Start后将保证至少 1000 毫秒的延迟,但不能保证确切地为 1000 毫秒。

最新更新