异步函数混淆的并行性

时间:2018-07-09 08:28:21

标签: c# task

我基于tutorial编写了示例代码。

我认为当运行TestAsync Task时,将打印“逻辑A”,然后使用“ await”关键字“ Logic C”进行打印。

但是它实际上就像同步方式一样运行,先打印“ Logic C”,然后打印“ Logic A”

class Program
{
    static void Main(string[] args)
    {
        TestAll();
    }

    static async void TestAll()
    {
        var y = TestAsync();

        // I want to do other jobs before task y finish
        Console.WriteLine("Logic A");

        int value = await y;
        Console.ReadLine();
    }

    static Task<int> TestAsync()
    {
        for (int i = 0; i < 20000; i++)
            ;
        Console.WriteLine("Logic C");
        return Task.FromResult(0);
    }
}

但是为什么先打印逻辑C然后再打印逻辑A?

enter image description here

谢谢答案,然后再问一个问题: 我希望“逻辑B”->“逻辑A”->“逻辑C”->“ 1”

但是它实际上只打印“逻辑B”->“逻辑A”并完成。

class Program
{
    static void Main(string[] args)
    {
        TestAll();
    }

    static async void TestAll()
    {
        var y = TestAsync();

        // I want to do other jobs before task y finish
        Console.WriteLine("Logic A");

        // delete this line will be correct, but I don't know why
        int value = await y;
        Console.WriteLine(value);
        Console.ReadLine();
    }

    static async Task<int> TestAsync()
    {
        Console.WriteLine("Logic B");
        await Task.Delay(100);
        Console.WriteLine("Logic C");
        return 1;
    }
}

1 个答案:

答案 0 :(得分:1)

如您所述,输出指示同步处理,因为它实际上是同步处理。

定义任务并不意味着异步处理。没有新的Task创建,您只将代码包装到Task,但没有创建新的Task。
如果要测试异步处理,则应修改方法:

private Task<int> TestAsync()
{
    return Task.Run(() =>
    {
        for (int i = 0; i < 20000; i++)
            ;
        Console.WriteLine("Logic C");
        return Task.FromResult(0);
    });
}

要回答您的另一个问题:

您没有所需的输出,因为您的Main方法没有等待异步操作完成。因此,当方法TestAll中的执行转到int value = await y;时,main方法将继续并正常完成。

更新您的Main方法以等待异步任务,您将获得所需的输出:

static void Main(string[] args)
{
   TestAll().Wait();
}

但是请看synchronously waiting on asynchronous task问题。它与上下文线程(UI线程,ASP上下文线程,...)相关,因此它对于控制台应用程序应该是安全的,但始终很了解what is behind