Is async always asynchronous in C#? [duplicate]

2019-02-28 17:39发布

This question already has an answer here:

I am doing R&D on async and await for my project. What I have learned is that when async method is called, it frees the thread and let the thread to be used by others. We can set callback for await-able method using await keyword and that method returns value when the result is ready. If that happens:

  1. We should be able to access the UI briefly between operations.
  2. Execution time should be faster than the usual synchronous method call.

In my case, I have no question about point 1, But for point 2, it's execution time seems same as the synchronous method call. For example see Sample Code 1 and Sample Output 1

Sample Code 1:

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Before Async Call");
            AsyncMethod();
            Console.WriteLine("After Async Call");

            Console.ReadLine();
        }

        public async static void AsyncMethod()
        {
            var firstValue = FirstAsyncMethod("FirstAsyncMethod has been called");
            Console.WriteLine("Middle of FirstAsyncMethod and SecondAsyncMethod");
            var secondValue = SecondAsyncMethod("SecondAsyncMethod has been called");
            Console.WriteLine(await firstValue);
            Console.WriteLine(await secondValue);
        }

        public static async Task<string> FirstAsyncMethod(string value)
        {
            for (int i = 0; i < 500000000; i++)
            {
                i = i + 1 - 1;
            }
            return "Success: "+value;
        }
        public static async Task<string> SecondAsyncMethod(string value)
        {
            for (int i = 0; i < 500000000; i++)
            {
                i = i + 1 - 1;
            }
            return "Success: " + value;
        }
    }

Sample Output 1:

Before Async Call
Middle of FirstAsyncMethod and SecondAsyncMethod
Success: FirstAsyncMethod has been called
Success: SecondAsyncMethod has been called
After Async Call

But if I call the async method with Task.Run(()=> ) (For example Sample Code 2 and Sample Output 2), it reduces the execution time compared to first example (Sample Code 1).

Sample Code 2:

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Before Async Call");
            AsyncMethod();
            Console.WriteLine("After Async Call");

            Console.ReadLine();
        }

        public async static void AsyncMethod()
        {
            var firstValue =Task.Run(()=> FirstAsyncMethod("FirstAsyncMethod has been called"));
            Console.WriteLine("Middle of FirstAsyncMethod and SecondAsyncMethod");
            var secondValue = Task.Run(() => SecondAsyncMethod("SecondAsyncMethod has been called"));
            Console.WriteLine(await firstValue);
            Console.WriteLine(await secondValue);
        }

        public static async Task<string> FirstAsyncMethod(string value)
        {
            for (int i = 0; i < 500000000; i++)
            {
                i = i + 1 - 1;
            }
            return "Success: "+value;
        }
        public static async Task<string> SecondAsyncMethod(string value)
        {
            for (int i = 0; i < 500000000; i++)
            {
                i = i + 1 - 1;
            }
            return "Success: " + value;
        }
    }

Sample Output 2:

Before Async Call
Middle of FirstAsyncMethod and SecondAsyncMethod
After Async Call
Success: FirstAsyncMethod has been called
Success: SecondAsyncMethod has been called

My question is, why the first example (Sample Code 1) taking time like synchronous method call?

1条回答
神经病院院长
2楼-- · 2019-02-28 18:11

Async is not always asynchronous. Visual Studio should display a warning that the first method is not asynchronous because there is nothing to await.

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread

Note that the use of async void is considered a bad practice these days. You should always use async Taks for the return type of async methods.

See this article for more information

查看更多
登录 后发表回答