.net 中的 async await ,求解惑

用async await做了几次试验,觉得这俩关键字很是邪门

写一个异步方法如下:

测试方法1:

class Program
{
    static void Main(string[] args)
    {
        var result = MyMethod(); //将异步执行
        
        Console.WriteLine("end");
        Console.ReadLine();
    }

    static async Task<int> MyMethod()
    {
        for (int i = 0; i < 5; i++)
        {
            await Task.Delay(1000); //模拟耗时操作

            Console.WriteLine("异步执行" + i.ToString() + "..");
        }
        return 0;
    }
}

输出结果:

clipboard.png

测试方法2:(Console.WriteLine(result.Result); //比方法1多了一行)

class Program
{
    static void Main(string[] args)
    {
        var result = MyMethod(); //将异步执行
        Console.WriteLine(result.Result); //比方法1多了一行
        
        Console.WriteLine("end");
        Console.ReadLine();
    }

    static async Task<int> MyMethod()
    {
        for (int i = 0; i < 5; i++)
        {
            await Task.Delay(1000); //模拟耗时操作

            Console.WriteLine("异步执行" + i.ToString() + "..");
        }
        return 0;
    }
}

输出结果:
clipboard.png

这里发现 方法二还是同步执行的,并没有异步执行,因为调用了值result.Result,导致方法同步执行了,也必须同步执行,否则 result 取不到值

测试方法3

class Program
{
    static void Main(string[] args)
    {
        var result = MyMethod(); 
        Console.WriteLine("end");
        Console.ReadLine();
    }

    static async Task<int> MyMethod()
    {
        for (int i = 0; i < 5; i++)
        {
            Console.WriteLine("异步执行" + i.ToString() + "..");

            await TestMethod();
        }
        return 0;
    }

    static Task TestMethod()
    {
        //死循环,永远执行
        while (true)
        {

        }
        return Task.CompletedTask;

    }
}

输出结果:

clipboard.png

测试方法3:发现 “Console.WriteLine("end");”这行代码没有输出,
也就是说 “var result = MyMethod();” 并没有异步执行,

目前我已经是凌乱状态,为什么没有异步执行MyMethod,
虽然TestMethod这里写的是一个死循环while (true){},但是我理解的预期效果应该是输出Console.WriteLine("end");
已经完全搞不懂 async 和 await

阅读 7.6k
3 个回答

google了一会儿,发现这个:

Async methods are intended to be non-blocking operations. An await expression in an async method doesn’t block the current thread while the awaited task is running. Instead, the expression signs up the rest of the method as a continuation and returns control to the caller of the async method. The async and await keywords don't cause additional threads to be created. Async methods don't require multithreading because an async method doesn't run on its own thread. The method runs on the current synchronization context and uses time on the thread only when the method is active. You can use Task.Run to move CPU-bound work to a background thread, but a background thread doesn't help with a process that's just waiting for results to become available.

主要意思应该是async/await并没有创建一个新的线程,因为TestMethod没有创建新的线程(比如使用Task.Run啊之类的),所以死循环还是会卡死当前的主线程的。
来源是:https://stackoverflow.com/que...,推荐看一看

测试方法1:是正常的异步写法,没有问题;
测试方法2:调用result.Result方法时,会阻塞主线程,直到异步结束;
测试方法3:await关键字是await之后的处理变成一个新线程,也就是说第一次执行TestMethod方法时,仍然是在主线程中执行,导致end永远不会被打印出来。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
logo
Microsoft
子站问答
访问
宣传栏