简体   繁体   中英

Task execution with and without await operator

I asked a question yesterday and the answer was good. But now I'm trying to understand the role of await and how task execution works.

I've read about await that: The await operator is applied to a task in an asynchronous method to suspend the execution of the method until the awaited task completes. The task represents ongoing work (from msdn site).

Task.run : The Run method allows you to create and execute a task in a single method call and is a simpler alternative to the StartNew method (from msdn site).

Now, with the code:

        public async Task YourFunc()
        {
            Exception error = null;
            try
            {
               var task = Task.Run(() =>
                         {
                             Thread.Sleep(3000);
                             throw new ArgumentException("test argument exception");
                         });
                var completed = task.IsCompleted;
                var faulted = task.IsFaulted;
                Console.WriteLine(completed);
                Console.WriteLine(faulted);
            }
            catch (Exception ex)
            {
                error = ex;
            }
            this.MigrationProcessCompleted(error);
        }

I've removed the await operator and I've set a breakpoint on the line Console.WriteLine(completed); . Why even after 2-3 minutes of waiting in this breakpoint, the task is not completed and not faulted? I've set a breakpoint inside the task's code and exception is trown, so the task must be marked as faulted or completed at least...

Nobody has really answered your question. You have a reasonable expectation to see task.isCompleted and task.isFaulted be true if you wait more than 3 seconds.

Your expectation is not wrong. The problem here is simply how the debugger is working. While you are stopped at that breakpoint waiting for things, all other threads are also stopped, so nothing is progressing and the exception has not been thrown yet.

This is just a quirk of debugging and you have a few options if you want to see the results you expect:

  1. Freeze the thread instead of using a breakpoint. In order to do this put a breakpoint right after the var task=Task.Run() and then open up your "threads" window in the debugger. Find the current thread (with the yellow arrow) right click on it and select "freeze" then hit F8 or click on continue to let the application keep running. After 3-4 seconds, click the "Pause" button on the debugger and double click on the frozen thread again. You can now check on the values of task.IsCompleted and task.IsFaulted and they should be true.
  2. Add a timeout before you check the tasks:

Code:

var task = Task.Run(() =>{
            Thread.Sleep(3000);
            throw new ArgumentException("test argument exception");
        });
        Thread.Sleep(5000);
        var completed = task.IsCompleted;
        var faulted = task.IsFaulted;
        Console.WriteLine("Completed ::" + completed);
        Console.WriteLine("Faulted ::" + faulted);  

Now you can put a breakpoint after the Thread.Sleep(5000) and confirm that the task is faulted/completed.

Keep in mind, that as others have said, use case of an immediately awaited Task.Run() is almost always a mistake. Keep in mind that the whole point of async/await is to free up the current thread so it's not doing useless waiting. If you do a Task.Run followed by an await you haven't achieved anything since you are just freeing up the current thread (putting it back in the thread pool) but the Task.Run() will take up a thread right back from the thread pool. Conceptually all your doing is moving your work form one thread id to another with no real gain (even if the work in your Task.Run is CPU-bound).

In that case, you are better off not doing Task.Run at all and just doing the work synchronously on the current thread.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM