这两种异步方法之间的区别是什么?

时间:2016-01-08 19:50:39

标签: c# asynchronous

所以我在C#中学习了async / await,我制作了一个小型Windows窗体应用程序,只用async / await。我想出了这些:

以下两种方法使用button1_Click

    private void button1_Click(object sender, EventArgs e)
    {
        GetSiteAsync();
    }

以下是该应用的外观:

enter image description here

方法1:

    public async void GetSiteAsync()
    {
        HttpClient ht = new HttpClient();
        Task<string> getTaskString = ht.GetStringAsync("http://stackoverflow.com");

        label1.Text = "Loading...";

        string siteString = await getTaskString;

        label1.Text = "Finished! Site Length = " + siteString.Length;
    }

方法2:

public async void GetSiteAsync()
{
    HttpClient ht = new HttpClient();
    string siteString = await ht.GetStringAsync("http://stackoverflow.com");

    label1.Text = "Loading...";

    label1.Text = "Finished! Site Length = " + siteString.Length;
}

在第一种方法中,当我点击“加载网址&#39;按钮,它将标签更改为&#39;等待...&#39;加载完成后,将其更改为“完成!”#39;附加网站长度。

在第二种方法中,当我点击按钮时,它不会更改标签,当操作完成时,它会将标签更改为网站长度。

我注意到两种方法导致程序GUI在加载网站时冻结。

那么为什么第二种方法无法将按钮更改为“正在加载...&#39; ??

3 个答案:

答案 0 :(得分:3)

await中的呼叫完成后执行await运算符后的代码。这可以在另一个线程中完成。在后台创建了一个状态机,我们说await之后的代码将继续执行。

所以在第一种情况下,

Task<string> getTaskString = ht.GetStringAsync("http://stackoverflow.com");
label1.Text = "Loading...";

您只需进行异步调用,然后设置Text的{​​{1}}值。

在第二种情况下,

label1

string siteString = await ht.GetStringAsync("http://stackoverflow.com"); label1.Text = "Loading..."; 这个电话。这意味着在完成此异步调用后,将执行await的setter。

答案 1 :(得分:2)

第二种方法会立即跳转到label1.Text = "Finished! Site Length = " + siteString.Length;行之后的label1.Text = "Loading...";行,因此您实际上从未看到它。第一种方法,你看,因为等待发生在之后。

所以: 第一种方法:&#34; loading&#34; - &GT;等待 - &gt; &#34;!成品&#34; 第二种方法:等待 - &gt; &#34;装载&#34; - &GT; &#34;成品&#34;!

&#34; loading&#34;立即用第二种方法写出来。

答案 2 :(得分:1)

在第一种方法中,您将标签测试设置为加载,然后await任务。

在第二种方法中你await任务(意味着你没有继续执行方法中的其余代码,直到它已经完成)和然后你将标签设置为加载(然后立即将其设置为完成)。

这些方法不会阻止UI线程,因为它们是异步的;它们很快将控制权返回给调用代码,并在产生控制权后继续工作。