快速提问,我希望在启动 异步任务之前等待一秒而不返回值。
这是正确的方法吗?
Task.Delay(1000)
.ContinueWith(t => _mq.Send(message))
.Start();
例外情况会怎样?
答案 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毫米完全。