c# - 为什么任务甚至在等待中完成

标签 c# async-await task-parallel-library task

我在下面的代码中遇到问题:

static void Main (string[] args)
{
    Task newTask = Task.Factory.StartNew(MainTask);
    newTask.ContinueWith ((Task someTask) => 
    {
        Console.WriteLine ("Main State=" + someTask.Status.ToString () + " IsFaulted=" + someTask.IsFaulted+" isComplete="+someTask.IsCompleted);
    });
    while (true) 
    {

    }
}

static async Task MainTask()
{
    Console.WriteLine ("MainStarted!");
    Task someTask = Task.Factory.StartNew (() => 
    {
        Console.WriteLine ("SleepStarted!");
        Thread.Sleep(1000);
        Console.WriteLine ("SleepEnded!");
    });
    await someTask;
    Console.WriteLine ("Waiting Ended!!");
    throw new Exception ("CustomException!");
    Console.WriteLine ("NeverReaches here!!");
}

我只想从新启动的任务 MainTask 中获取异常。但结果并不是我所期望的。

MainStarted!
Main State = RanToCompletion IsFaulted = False isComplete = True
SleepStarted!
SleepEnded!
Waiting Ended!!

如您所见,任务在“Waiting Ended!!”之前完成控制台日志。 我不知道为什么 MainTask 即使在 MainTask 中有 await 命令也结束了? 我错过了什么吗?

最佳答案

Task.Factory.StartNew does not understand async delegates所以在这种情况下您需要使用 Task.Run 并且异常应该流过。

Task.Factory.StartNew(MainTask);

本质上等同于

Task.Factory.StartNew(() => MainTask);

它忽略了从 MainTask 返回的任务并且异常被吞没了。

查看此 blog post了解更多详情。

尝试使用 Task.Run 代替,你会得到你的异常:

void Main(string[] args)
{
    Task newTask = Task.Run(MainTask);
    newTask.ContinueWith((Task someTask) =>
   {
       Console.WriteLine("Main State=" + someTask.Status.ToString() + " IsFaulted=" + someTask.IsFaulted + " isComplete=" + someTask.IsCompleted);
   });
    while (true)
    {

    }
}

static async Task MainTask()
{
    Console.WriteLine("MainStarted!");
    Task someTask = Task.Run(() =>
   {
       Console.WriteLine("SleepStarted!");
       Thread.Sleep(1000);
       Console.WriteLine("SleepEnded!");
   });
    await someTask;
    Console.WriteLine("Waiting Ended!!");
    throw new Exception("CustomException!");
    Console.WriteLine("NeverReaches here!!");
}

关于c# - 为什么任务甚至在等待中完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32390593/

相关文章:

c# - 任务以及如何正确使用它们 C#

c# - 充分利用 .NET 任务并行库

c# - 绘图板/手写笔库

javascript - NodeJS 路由器使用另一个调用请求的函数不等待应答

c# - 是否将 Task<>.Factory.StartNew/Task.Factory.ContinueWhenAll() 转换为 async/await?

c# - 将 Task<T> 用于非实时任务

c# - 使用 ASP.NET MVC 异步 Controller 方法处理多个用户请求

C# 符号

c# - 当多个线程生成的进程将文件复制到同一目录 C# 时缺少文件条目

c# - 为什么这个 async/await 代码会生成 "...not all code paths return a value"?