Async always WaitingForActivation

后端 未结 5 1088
夕颜
夕颜 2020-12-02 21:50

I am trying to figure out what the async & await keywords are all about, however the output isn\'t what I\'m expecting.

The console app

5条回答
  •  無奈伤痛
    2020-12-02 22:42

    The reason is your result assigned to the returning Task which represents continuation of your method, and you have a different Task in your method which is running, if you directly assign Task like this you will get your expected results:

    var task = Task.Run(() =>
            {
                for (int i = 10; i < 432543543; i++)
                {
                    // just for a long job
                    double d3 = Math.Sqrt((Math.Pow(i, 5) - Math.Pow(i, 2)) / Math.Sin(i * 8));
                }
               return "Foo Completed.";
    
            });
    
            while (task.Status != TaskStatus.RanToCompletion)
            {
                Console.WriteLine("Thread ID: {0}, Status: {1}", Thread.CurrentThread.ManagedThreadId,task.Status);
    
            }
    
            Console.WriteLine("Result: {0}", task.Result);
            Console.WriteLine("Finished.");
            Console.ReadKey(true);
    

    The output:

    enter image description here

    Consider this for better explanation: You have a Foo method,let's say it Task A, and you have a Task in it,let's say it Task B, Now the running task, is Task B, your Task A awaiting for Task B result.And you assing your result variable to your returning Task which is Task A, because Task B doesn't return a Task, it returns a string. Consider this:

    If you define your result like this:

    Task result = Foo(5);
    

    You won't get any error.But if you define it like this:

    string result = Foo(5);
    

    You will get:

    Cannot implicitly convert type 'System.Threading.Tasks.Task' to 'string'

    But if you add an await keyword:

    string result = await Foo(5);
    

    Again you won't get any error.Because it will wait the result (string) and assign it to your result variable.So for the last thing consider this, if you add two task into your Foo Method:

    private static async Task Foo(int seconds)
    {
        await Task.Run(() =>
            {
                for (int i = 0; i < seconds; i++)
                {
                    Console.WriteLine("Thread ID: {0}, second {1}.", Thread.CurrentThread.ManagedThreadId, i);
                    Task.Delay(TimeSpan.FromSeconds(1)).Wait();
                }
    
                // in here don't return anything
            });
    
       return await Task.Run(() =>
            {
                for (int i = 0; i < seconds; i++)
                {
                    Console.WriteLine("Thread ID: {0}, second {1}.", Thread.CurrentThread.ManagedThreadId, i);
                    Task.Delay(TimeSpan.FromSeconds(1)).Wait();
                }
    
                return "Foo Completed.";
            });
    }
    

    And if you run the application, you will get the same results.(WaitingForActivation) Because now, your Task A is waiting those two tasks.

提交回复
热议问题