Not awaiting an async call is still async, right?

后端 未结 2 1545
隐瞒了意图╮
隐瞒了意图╮ 2021-01-04 01:06

I\'m sorry if this is a silly question (or a duplicate).

I have a function A:

public async Task A(/* some parameters */)
{
           


        
2条回答
  •  隐瞒了意图╮
    2021-01-04 01:10

    You are right. Creating a task does only that and it does not care when and who will await its result. Try putting await Task.Delay(veryBigNumber); in SomeOtherFuncAsync and the console output should be what you would expect.

    This is called eliding and I suggest you read this blogpost, where you can see why you should or should not do such thing.

    Also some minimal (little convoluted) example copying your code proving you right:

    class Program
        {
            static async Task Main(string[] args)
            {
                Console.WriteLine($"Start of main {Thread.CurrentThread.ManagedThreadId}");
                var task = First();
                Console.WriteLine($"Middle of main {Thread.CurrentThread.ManagedThreadId}");
                await task;
                Console.WriteLine($"End of main {Thread.CurrentThread.ManagedThreadId}");
            }
    
            static Task First()
            {
                return SecondAsync();
            }
    
            static async Task SecondAsync()
            {
                await ThirdAsync();
            }
    
            static async Task ThirdAsync()
            {
                Console.WriteLine($"Start of third {Thread.CurrentThread.ManagedThreadId}");
                await Task.Delay(1000);
                Console.WriteLine($"End of third {Thread.CurrentThread.ManagedThreadId}");
            }
        }
    

    This writes Middle of main before End of third, proving that it is in fact asynchronous. Furhtermore you can (most likely) see that the ends of functions run on different thread than the rest of the program. Both beginnings and the middle of main will always run on the same thread because those are in fact synchrnous (main starts, calls the function chain, third returns (it may return at the line with the await keyword) and then main continues as if there was no asynchronous function ever involved. The endings after the await keywords in both functions may run on any thread in the ThreadPool (or in synchronization context you are using).

    Now it is interesting to note, that if Task.Delay in Third did not take very long and actually finished synchronously, all of this would run on a single thread. What's more, even though it would run asynchronously, it might all run on a single thread. There is no rule stating that an async function will use more than one thread, it may very well just do some other work while waiting for some I/O task to finish.

提交回复
热议问题