c# - 等待任务完成,在 'await' 之后进行操作

标签 c# async-await

我知道我可能会被否决,但显然我对 async-await 的理解不够,我发现的问题/答案以及我发现的文章并没有帮助我找到这个问题的答案:
如何使“2”打印出来?或者实际上,为什么在 await t 和 t.Wait() 中都没有打印出 2 ?:

static Task t;
public static async void Main()
{
    Console.WriteLine("Hello World");
    t = GenerateTask();     
    await t;
    //t.Wait();
    Console.WriteLine("Finished");
}

public static Task GenerateTask()
{
    var res = new Task(async () => 
    {
        Console.WriteLine("1");
        await Task.Delay(10000);
        Console.WriteLine("2"); 
    });
    res.Start();
    return res;
}
编辑:我正在创建一个任务并返回它,因为在现实生活中我需要稍后通过不同的方法等待这个任务。
Edit2:await Task.Delay 只是不同功能上实际等待的占位符。

最佳答案

打印“2”
实际打印的是 2,在打印 1 后 10 秒。如果您添加 Console.ReadLine();,您可以观察到这一点打印“完成”后。
输出是

Hello World
1
Finished
2
怎么了?
当您等待 t (在 res 方法中是 GenerateTask)您正在等待创建的任务而不是 res 的任务创建的。
如何修复(花哨的方式)
您将需要等待外部任务和内部任务。为了能够等待内部任务,您需要公开它。要公开它,您需要从 Task 更改任务的类型至Task<Task>以及来自 Task 的返回类型至Task<Task> .
它可能看起来像这样:
public static async Task Main()
{
    Console.WriteLine("Hello World");
    var outerTask = GenerateTask();     
    var innerTask = await outerTask; // what you have 
    await innerTask;                 // extra await
    Console.WriteLine("Finished");
    Console.ReadLine();
}

public static Task<Task> GenerateTask() // returns Task<Task>, not Task
{
    var res = new Task<Task>(async () => // creates Task<Task>, not Task
    {
        Console.WriteLine("1");
        await Task.Delay(TimeSpan.FromSeconds(10));
        Console.WriteLine("2"); 
    });
    res.Start();
    return res;
}
现在的输出是:
Hello World
1
2
Finished
如何修复(简单的方法)
不需要外部任务。
public static async Task Main()
{
    Console.WriteLine("Hello World");
    var t  = GenerateTask();     
    await t;
    Console.WriteLine("Finished");
    Console.ReadLine();
}

public static async Task GenerateTask()
{
    Console.WriteLine("1");
    await Task.Delay(TimeSpan.FromSeconds(10));
    Console.WriteLine("2"); 
}

关于c# - 等待任务完成,在 'await' 之后进行操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66839901/

相关文章:

c# - 为什么 Unity 会在此处抛出错误 CS0136 而 Visual Studio 2019 不会?

javascript - 如何异步处理未处理的 promise 拒绝?

c# - 操作运行时异步取消

c# - 忽略异步任务方法的返回值

c# - 如何将字符串与 nhibernate 进行比较?

c# - MSIL 问题(基本)

c# - 如何将 FirstOrDefault 与 Include 一起使用?

c# - 如何从字符串列表中获取字符串?

node.js - TsLint 提示调用顶级异步方法

c# - 任务在 C# 中返回一个 StreamReader