简体   繁体   English

async方法阻止它正在执行的UI线程

[英]async method is blocking UI thread on which it is executing

Consider the following codes in Winform. 在Winform中考虑以下代码。 When I clicked the button, I was expecting that the async method should not block UI thread on which it was executing. 当我单击该按钮时,我希望async方法不应该阻止它正在执行的UI线程。

However, I found out that button was frozen during async method calling... If true, what is the point of async method? 但是,我发现在异步方法调用期间该按钮被冻结...如果为true,异步方法有什么意义? 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;
        }
    }
}

The compiler warning tells you exactly what's going on: since your async method does not ever await , it will run synchronously. 编译器警告会告诉您到底发生了什么:由于您的async方法无法await ,因此它将同步运行。

Thread.Sleep is a synchronous operation; Thread.Sleep是一个同步操作; if you want to fake an asynchronous operation, use Task.Delay : 如果要伪造异步操作,请使用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;
}

Currently you're lacking await in the AccessTheWebAsync because you do not await anything so all code runs on the main thread. 当前,AccessTheWebAsync中缺少等待,因为您没有等待,因此所有代码都在主线程上运行。 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. (可选)您可以使用库内部常用的ConfigureAwait ,以便等待后的所有操作都将在等待完成的同一线程中进行。

Checkout http://blogs.msdn.com/b/pfxteam/archive/2012/04/12/async-await-faq.aspx for some more information about async/await. 有关async / await的更多信息,请访问http://blogs.msdn.com/b/pfxteam/archive/2012/04/12/async-await-faq.aspx

When you write such code: 当你写这样的代码时:

private async Task<int> DoStuffAsync()
{
    return 0;
}

This way you are doing things synchronously, because you are not using await expression. 这样你就可以同步处理,因为你没有使用await表达式。

Pay attention to the warning: 注意警告:

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Based on the warning suggestion you can correct it this way: 根据警告建议,您可以这样纠正:

private async Task<int> DoStuffAsync()
{
    return await Task.Run<int>(() =>
    {
        return 0;
    });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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