代码之家  ›  专栏  ›  技术社区  ›  arynaq

async和await,在main中应为非阻塞

  •  0
  • arynaq  · 技术社区  · 7 年前

    从我对 async 关键字的用法 await in combination用于在实际需要异步操作的结果时创建一个延续点,允许在此期间完成其他工作。

    那为什么下面的阻塞呢?我希望 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);
    }
    

    它被称为main

    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
    

    这意味着我在这个上下文中阻塞,所有的东西都是按顺序链接在一起的。。。我不明白什么?

    1 回复  |  直到 7 年前
        1
  •  3
  •   A Friend    7 年前

    Microsoft Docs :

    通过写作 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}");
    }
    

    然后 等待任务完成,然后再尝试输出结果。