延迟然后执行任务

时间:2013-10-31 10:17:21

标签: c# .net asynchronous task-parallel-library

快速提问,我希望在启动 异步任务之前等待一秒而不返回值。
这是正确的方法吗?

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

例外情况会怎样?

3 个答案:

答案 0 :(得分:36)

首先,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(),请考虑使用{{1}}。

答案 1 :(得分:11)

如果等待任务完成,您可以捕获任务中抛出的任何异常:

请注意,您在任务中抛出的异常将成为内部异常

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

答案 2 :(得分:0)

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

  

正在运行的用户代码引发的未处理异常   任务内部传播回连接线程,除了   本主题后面介绍的某些方案。例外   当您使用静态或实例Task.Wait或其中一个时传播   Task.Wait方法,你通过封闭调用来处理它们   在try-catch语句中。

摘录自Exception Handling (Task Parallel Library)

小心时间。任务使用调度程序,并且不保证在您说“去”时启动。在将代码告知Start后,您的代码将保证至少 1000毫秒延迟,但不能保证1000毫米完全