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
只是一个自定义实现,允许我排队并执行任务)

As
Task.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()
修复了问题。如果您将此作为答案添加,我会将其设置为已批准的答案。