快速问题,我想在启动没有返回值的异步任务之前等待一秒钟.
这是正确的方法吗?
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 毫秒。