簡體   English   中英

異步並等待,期望在主程序中不阻塞

[英]async and await, expecting non-blocking in 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}");
}

然后您的程序將打印預期的行, 然后等待任務完成,然后再嘗試輸出結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM