异步并等待,期望在主程序中不阻塞

时间:2018-10-09 10:33:41

标签: c# asynchronous

根据我对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

这意味着我在这种情况下处于阻塞状态,并且所有内容都按顺序链接在一起...我不了解什么?

1 个答案:

答案 0 :(得分:3)

来自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}");
}

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