异步和等待,期望在 main 中不阻塞



根据我对async关键字的理解,组合使用await用于在实际需要异步操作的结果时创建一个延续点,从而允许在此期间完成其他工作。

那为什么会阻止以下呢?我希望Nothing to do while the awaits complete, expecting this line to come first.是控制台输出的第一行。

tasks.cs

public static async Task Execute()
{
var sw = new Stopwatch();
sw.Start();
await Foo();
sw.Stop();
Console.WriteLine($"Execute completed in {sw.ElapsedMilliseconds}ms.");
}
private static async Task Foo()
{
var tasks = Enumerable.Range(0, 5).Select(x =>
{
return Task.Factory.StartNew((b) =>
{
Thread.Sleep(100);
int value = (int) b;
Console.WriteLine($"Task ran on thread: {Thread.CurrentThread.ManagedThreadId}");
return value * value;
}, x);
}).ToArray();
await Task.WhenAll(tasks);
}

在主中称为

static async Task Main(string[] args)
{
await Tasks.Execute();
var result = await LongRunningOperation();
Console.WriteLine("Nothing to do while the awaits complete, expecting this line to come first.");
Console.WriteLine($"Long running operation result: {result}");
}
private static async Task<int> LongRunningOperation()
{
var sw = new Stopwatch();
sw.Start();
var res = await Task.Factory.StartNew(() =>
{
Thread.Sleep(10000);
Console.WriteLine($"Long running operation completed on thread {Thread.CurrentThread.ManagedThreadId}");
return 10000;
});
sw.Stop();
return res;
}

输出以下内容:

Task ran on thread: 7
Task ran on thread: 4
Task ran on thread: 3
Task ran on thread: 5
Task ran on thread: 6
Execute completed in 113ms.
Long running operation completed on thread 9
Nothing to do while the awaits complete, expecting this line to come first.
Long running operation result: 10000

这意味着我在这种情况下被阻止,并且所有内容都按顺序链接在一起......我不明白什么?

来自Microsoft Docs:

await 运算符应用于异步方法中的任务,以在方法执行中插入挂起点,直到等待的任务完成

通过写var result = await LongRunningOperation();,您将暂停任何进一步的操作,直到LongRunningOperation完成。

如果将Main重写为如下所示:

static async Task Main(string[] args)
{
var longTask = LongRunningOperation();
Console.WriteLine("Nothing to do while the awaits complete, expecting this line to come first.");
var result = await longTask;
Console.WriteLine($"Long running operation result: {result}");
}

然后,程序将打印预期的行,然后在尝试输出结果之前等待任务完成。

最新更新