none
When is async not async RRS feed

  • Question

  • Hi,

    What can cause an async task to run synchronously?

    In the following code, msg_box.Text gets set to "Process started" because - msg_box.Text = "Process started" -  isn't executed until process() finishes.

    I've used async before and never had a problem with it until now. 

    Does process need to actually reach an Async call before control continues after the process() call, because that may be the reason. None of the documentation on async says that.

    Dave

    private void Process_Button_Click(object sender, EventArgs e)
            {
                Task t = process();
                msg_box.Text = "Process started";
            }
    
            async Task process()
            {
                .....
                .....
                msg_box.Text = "Process finished";
            }

    Monday, August 11, 2014 3:09 AM

Answers

  • This executes in sync:

    private void Process_Button_Click(object sender, EventArgs e)
    {
        Task t = process();
        button1.Text = "Process started";
    }
    
    private async Task process()
    {
        button1.Text = "Process finished";
    }

    This includes an await and runs async:

    private void Process_Button_Click(object sender, EventArgs e)
    {
        Task t = process();
        button1.Text = "Process started";
    }
    
    private async Task process()
    {
        await Task.Delay(5000);
        button1.Text = "Process finished";
    }


    Monday, August 11, 2014 9:34 AM
  • Not true, Await simply waits for an async task to complete.

    await makes the method run asynchronously, the async keyword just enables await, it does nothing on its own so your code runs completely synchronously.

    The await checks whether the operation completed; if it's completed it behaves synchronously otherwise it will behave asynchronously and let the operation run in the background or main thread when possible and continue to the next item to execute.


    Regards, Eyal Shilony

    Monday, August 11, 2014 10:05 AM
    Moderator
  • An async process will only run async if all the methods inside the code do not block.  A Delay is a blocking method.  So if the Delay is in the main thread the async will run, but if the Delay is in the child thread the main thread is block. 

    jdweng

    Monday, August 11, 2014 11:08 AM
  • Hello,

    Here is a simple example

    private void button1_Click(object sender, EventArgs e)
    {
       Demo();
    }
    async void Demo()
    {
        Task t = new Task
        (
            () =>
            {
                Console.WriteLine("Starting...");
                Thread.Sleep(3000);                   
                Console.WriteLine("Ended the task");
            }
        );
    
        // start the task
        t.Start();
    
        await t;
        Console.WriteLine("After await");
    }


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem.

    Monday, August 11, 2014 1:07 PM
    Moderator

All replies

  • should it run automatically or am i missing t.Start()?
    Monday, August 11, 2014 3:18 AM
  • Seems like your assumption is correct.

    "The method runs synchronously until it reaches its first await expression, at which point the method is suspended until the awaited task is complete."

    Source: async (C# Reference)


    • Proposed as answer by ThankfulHeart Monday, August 11, 2014 5:08 AM
    • Marked as answer by Dave Mullard Monday, August 11, 2014 9:16 AM
    • Unmarked as answer by Dave Mullard Monday, August 11, 2014 9:18 AM
    Monday, August 11, 2014 5:06 AM
  • await make a task async. You miss await.
    Monday, August 11, 2014 6:05 AM
  • A Task doesn't do anything until you tell it to do.

    So you can either start it ( and ignore async await ) or you can await it.

    Just setting a variable to it doesn't make it do stuff.

    Monday, August 11, 2014 7:29 AM
    Moderator
  • Seems like your assumption is correct.

    "The method runs synchronously until it reaches its first await expression, at which point the method is suspended until the awaited task is complete."

    Source: async (C# Reference)



    That isn't strictly true. What happens is that process runs synchronously until it reaches an await on an async operation. My problem is that, under some circumstances, Process completes without ever executing one and so runs completely synchronously.
    Monday, August 11, 2014 9:25 AM
  • Your problem in that code is that you are not doing the process.

    You may as well be doing

                string x = "blaa";
                msg_box.Text = "Process started";

    You are assigning the task to a task but not doing anything with it.
    Monday, August 11, 2014 9:29 AM
    Moderator
  • await make a task async. You miss await.

    Not true, Await simply waits for an async task to complete.
    Monday, August 11, 2014 9:31 AM
  • This executes in sync:

    private void Process_Button_Click(object sender, EventArgs e)
    {
        Task t = process();
        button1.Text = "Process started";
    }
    
    private async Task process()
    {
        button1.Text = "Process finished";
    }

    This includes an await and runs async:

    private void Process_Button_Click(object sender, EventArgs e)
    {
        Task t = process();
        button1.Text = "Process started";
    }
    
    private async Task process()
    {
        await Task.Delay(5000);
        button1.Text = "Process finished";
    }


    Monday, August 11, 2014 9:34 AM
  • Not true, Await simply waits for an async task to complete.

    await makes the method run asynchronously, the async keyword just enables await, it does nothing on its own so your code runs completely synchronously.

    The await checks whether the operation completed; if it's completed it behaves synchronously otherwise it will behave asynchronously and let the operation run in the background or main thread when possible and continue to the next item to execute.


    Regards, Eyal Shilony

    Monday, August 11, 2014 10:05 AM
    Moderator
  • An async process will only run async if all the methods inside the code do not block.  A Delay is a blocking method.  So if the Delay is in the main thread the async will run, but if the Delay is in the child thread the main thread is block. 

    jdweng

    Monday, August 11, 2014 11:08 AM
  • Hello,

    Here is a simple example

    private void button1_Click(object sender, EventArgs e)
    {
       Demo();
    }
    async void Demo()
    {
        Task t = new Task
        (
            () =>
            {
                Console.WriteLine("Starting...");
                Thread.Sleep(3000);                   
                Console.WriteLine("Ended the task");
            }
        );
    
        // start the task
        t.Start();
    
        await t;
        Console.WriteLine("After await");
    }


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem.

    Monday, August 11, 2014 1:07 PM
    Moderator
  • Not true, Await simply waits for an async task to complete.

    await makes the code run asynchronously, the async keyword just enables await, it does nothing on its own so your code runs completely synchronously.

    The await checks whether the operation completed; if it's completed it behaves synchronously otherwise it will behave asynchronously and let the operation run in the background or main thread when possible and continue to the next item to execute.


    Regards, Eyal Shilony


    Await does not make the code run asynchronously, all code will be synchronously but await make a method asynchronously because it contains await. Otherwise it will be synchronously, it has no await.
    Monday, August 11, 2014 2:45 PM
  • Await does not make the code run asynchronously, all code will be synchronously but await make a method asynchronously because it contains await. Otherwise it will be synchronously, it has no await.

    You can only put the async/await pair on a method so when I wrote code I actually referred to a method but I agree that a method is the better term to use in the context of this post.

    I'll update my post, thanks.


    Regards, Eyal Shilony

    Tuesday, August 12, 2014 2:30 PM
    Moderator