Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

async method is blocking UI thread on which it is executing

Tags:

c#

async-await

Consider the following codes in Winform. When I clicked the button, I was expecting that the async method should not block UI thread on which it was executing.

However, I found out that button was frozen during async method calling... If true, what is the point of async method? I am confused.

namespace WindowsFrmAsyn
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        async private void button1_Click(object sender, EventArgs e)
        {
            int contentlength = await AccessTheWebAsync();
            tbResult.Text =
                        string.Format("Length of the downloaded string: {0}.", contentlength);

            Debug.WriteLine(tbResult.Text);
        }    

        async Task<int> AccessTheWebAsync()
        {
            Debug.WriteLine("Call AccessTheWebAsync");
            Thread.Sleep(5000);
            Debug.WriteLine("Call AccessTheWebAsync done");
            tbResult.Text = "I am in AccessTheWebAsync";
            return 1000;
        }
    }
}
like image 815
user3918459 Avatar asked Jan 11 '23 00:01

user3918459


2 Answers

The compiler warning tells you exactly what's going on: since your async method does not ever await, it will run synchronously.

Thread.Sleep is a synchronous operation; if you want to fake an asynchronous operation, use Task.Delay:

async Task<int> AccessTheWebAsync()
{
  Debug.WriteLine("Call AccessTheWebAsync");
  await Task.Delay(5000);
  Debug.WriteLine("Call AccessTheWebAsync done");
  tbResult.Text = "I am in AccessTheWebAsync";
  return 1000;
}
like image 105
Stephen Cleary Avatar answered Jan 26 '23 01:01

Stephen Cleary


Currently you're lacking await in the AccessTheWebAsync because you do not await anything so all code runs on the main thread. Async/await doesn't make the method run on a different thread except the part that you await.

The method must be something like this.

async Task<int> AccessTheWebAsync()
{
     // Console writeline
     await Task.Delay(seconds);
     // Console WriteLine.
     return value;
}

So everything before and after an await inside the async method is run on the same thread the method has been called. Optionally you can use ConfigureAwait that is commonly used inside libraries so that everything after the await will occur at the same thread the await has been done.

Checkout http://blogs.msdn.com/b/pfxteam/archive/2012/04/12/async-await-faq.aspx for some more information about async/await.

like image 21
Martijn van Put Avatar answered Jan 26 '23 01:01

Martijn van Put