簡體   English   中英

async方法阻止它正在執行的UI線程

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

在Winform中考慮以下代碼。 當我單擊該按鈕時,我希望async方法不應該阻止它正在執行的UI線程。

但是,我發現在異步方法調用期間該按鈕被凍結...如果為true,異步方法有什么意義? 我很困惑。

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;
        }
    }
}

編譯器警告會告訴您到底發生了什么:由於您的async方法無法await ,因此它將同步運行。

Thread.Sleep是一個同步操作; 如果要偽造異步操作,請使用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;
}

當前,AccessTheWebAsync中缺少等待,因為您沒有等待,因此所有代碼都在主線程上運行。 異步/等待不會使方法在等待的部分之外的其他線程上運行。

方法必須是這樣的。

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

因此,異步方法內部等待之前和之后的所有操作都在已調用該方法的同一線程上運行。 (可選)您可以使用庫內部常用的ConfigureAwait ,以便等待后的所有操作都將在等待完成的同一線程中進行。

有關async / await的更多信息,請訪問http://blogs.msdn.com/b/pfxteam/archive/2012/04/12/async-await-faq.aspx

當你寫這樣的代碼時:

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

這樣你就可以同步處理,因為你沒有使用await表達式。

注意警告:

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.

根據警告建議,您可以這樣糾正:

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