C# Task.Factory.StartNew()不';使用ContinueWith()时不包括异常
我正在尝试创建一个并行进程,它不会阻塞我的主线程,但仍会记录错误,以防出现异常。最初我有这样的代码:C# Task.Factory.StartNew()不';使用ContinueWith()时不包括异常,c#,asynchronous,async-await,task,task-parallel-library,C#,Asynchronous,Async Await,Task,Task Parallel Library,我正在尝试创建一个并行进程,它不会阻塞我的主线程,但仍会记录错误,以防出现异常。最初我有这样的代码: var task = Task.Run( () => _db.addData()); task.ContinueWith(continuationTask => { if (continuationTask.Exception != null) { _logger.LogError(continuationTa
var task = Task.Run(
() => _db.addData());
task.ContinueWith(continuationTask =>
{
if (continuationTask.Exception != null)
{
_logger.LogError(continuationTask.Exception, "Failed to log mismatch");
}
},
_taskScheduler);
运行应用程序时,代码\u taskScheduler
设置为taskScheduler.Current
。
运行此操作时,它会正确地并行执行代码,当数据库出现问题时,continuationTask.Exception
包含相应的异常消息
指定TaskScheduler
的全部目的是为了控制单元测试中的执行顺序。目前,在单元测试中,原始任务和后续任务将分别使用不同的任务调度器运行-TaskScheduler
和MockTaskScheduler
。(为了简洁起见,没有显示单元测试代码,但MockTaskScheduler
只是一个自定义实现,允许我排队并执行任务)
AsTask.Run
没有将TaskScheduler
作为我尝试将代码更改为的参数
var task = Task.Factory.StartNew(
() => _db.addData(),
CancellationToken.None,
TaskCreationOptions.None,
_taskScheduler);
task.ContinueWith(continuationTask =>
{
if (continuationTask .Exception != null)
{
_logger.LogError(continuationTask.Exception, "Failed to log mismatch");
}
},
_taskScheduler);
这使得我的测试可以完美地工作,因为我现在可以控制每个任务何时执行,因为它们使用相同的可注入\u taskScheduler
。但是,当使用TaskScheduler.Current
运行应用程序代码时,continuationTask.Exception
始终为空,从而阻止我记录任何异常
为什么
Task.Run
填充continuationTask.Exception
和Task.Factory.StartNew
不填充?我遗漏了什么吗?正如@Mike Zboray在评论中提到的,我需要调用task.Unwrap().ContinueWith()
,因为我有嵌套的任务。这仅在使用Task.Factory.StartNew()
作为Task.Run()
自动展开嵌套任务时才有必要
我的最终代码如下所示:
var task = Task.Factory.StartNew(
() => _db.addData(),
CancellationToken.None,
TaskCreationOptions.None,
_taskScheduler);
task.Unwrap().ContinueWith(continuationTask =>
{
if (continuationTask .Exception != null)
{
_logger.LogError(continuationTask.Exception, "Failed to log mismatch");
}
},
_taskScheduler);
设置当前计划程序的原因是
继续执行
而不是任务。请运行
。使用等待任务。运行。
我不想等待任务,这将使我的代码同步。您的代码已经是异步的,但只是使用了另一种语法。根据addData的返回类型,第二种情况下任务
可能是,任务
。运行自动展开这样的内部任务,但如果您使用StartNew,则必须手动执行。尝试task.Unwrap().ContinueWith(…
)。感谢@MikeZboray的帮助。返回类型addData
确实是一个任务。正如所建议的,内部任务的异常似乎丢失了。添加task.Unwrap().ContinueWith()
修复了问题。如果您将此作为答案添加,我会将其设置为已批准的答案。