我也收到这个错误:
代码块如下所示:
private void CallMediator<TRequest>(TRequest request) where TRequest : IRequest<Unit>
{
_ = Task.Run(async () =>
{
var mediator = _serviceScopeFactory.CreateScope().ServiceProvider.GetService<IMediator>()!;
await mediator.Send(request).ContinueWith(LogException, TaskContinuationOptions.OnlyOnFaulted);
});
}
private void LogException(Task task)
{
if (task.Exception != null)
{
_logger.LogError(task.Exception, "{ErrorMessage}", task.Exception.Message);
}
}
阅读相关文档继续 https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.continuewith?view=net-6.0#system-threading-tasks-task-continuewith(system-action((system-threading-tasks-task))-system-threading-tasks-taskcontinuationoptions)方法,其备注如下:
在当前任务完成之前,返回的任务不会被安排执行。如果通过指定的延续标准continuationOptions
参数不满足,继续任务将被取消的预定的。
所以对我来说,它称为第一个任务(mediator.Send(request)
),然后继续执行任务ContinueWith(...)
,这是我await
编辑。然而,由于第一个任务没有发生异常,因此第二个任务被取消。因此,在等待第二个任务时,它抛出了一个TaskCanceledException
.
我所做的是将代码更改为:
private void CallMediator<TRequest>(TRequest request) where TRequest : IRequest<Unit>
{
_ = Task.Run(async () =>
{
var mediator = _serviceScopeFactory.CreateScope().ServiceProvider.GetService<IMediator>()!;
try
{
_ = await mediator.Send(request);
}
catch (Exception ex)
{
_logger.LogError(ex, "{ErrorMessage}", ex.Message);
}
});
}
而不是使用.ContinueWith(...)
,我已将其替换为常规的 try-catch 块,以防我感兴趣的任务失败。我认为这简化了代码并使其更具可读性。
问题中,有这样一行代码:
Task.Delay(1000).ContinueWith(t => Console.WriteLine("{0}", t.Exception), TaskContinuationOptions.OnlyOnFaulted).Wait();
我会将其重写为:
try
{
Task.Delay(1000).Wait();
}
catch (Exception ex)
{
Console.WriteLine("{0}", ex);
}