为什么WinForms应用程序中的这个Textbox会破坏?

时间:2017-01-03 04:37:58

标签: c# .net winforms asynchronous

我正在阅读Jeffrey Richter的书,CLR通过C#第4版。作者在本书中讨论了异步编程,并指出了GUI应用程序中的一个问题,例如WinForms或WPF应用程序,其中同步调用异步方法,这会导致GUI线程被阻塞。

我在Visual Studio 2015中创建了一个开箱即用的WinForms应用程序,并输入了本书中讨论的方法。代码获取一个Task,然后Form使用Result属性来设置Form上的Textbox。我在下面的表单中包含了部分类定义。

问题是在执行此操作后TextBox被破坏。破碎我的意思是不可能输入文本框。此外,TextBox在设置TextBox的Text属性后实际上不显示文本。我不相信问题出在Richter的书中。在调试器中运行应用程序后,我实际上可以看到请求的页面的html为字符串。

为什么TextBox会中断?

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

    private void button1_Click(object sender, EventArgs e)
    {
        textBox1.MaxLength = 0;
        string page = GetHttp().Result;
        textBox1.Text = page;


    }           

    private Task<String> GetHttp()
    {

       return Task.Run(async () =>
       {
           // Issue the HTTP request and let the thread return from GetHttp
           HttpResponseMessage msg = await new HttpClient().GetAsync("http://www.techspot.com");
           return await msg.Content.ReadAsStringAsync();
       });   

    }
}

3 个答案:

答案 0 :(得分:0)

不要在TextBox上设置MaxLength属性。

答案 1 :(得分:0)

答案是文本框是单行文本框。使文本框成为多行文本框(我省略了,拍打前额)会导致代码正常运行。

答案 2 :(得分:-1)

为了澄清您的代码不会运行异步。您没有在这里以正确的方式实现async / await模式。如果使用GetHttp().Result;,则可能会成为死锁,因为.Result阻塞并等待您的任务完成。相反,您应该使用await来确保您的任务已完成。进一步等待不会阻止您的UI,也不会导致死锁。我准备了您的代码并使用了正确的名称约定:

private async void button1_Click(object sender, EventArgs e)
{
    //Notice that .Result or .Wait on Gui-Thread can cause a Deadlock!!!
    string page = await GetHttpAsync();
    textBox1.Text = page;
}           

private async Task<String> GetHttpAsync()
{
   //Make sure you don't need any Task here. The await makes this async
   HttpResponseMessage msg = await new HttpClient().GetAsync("http://www.techspot.com");
   return await msg.Content.ReadAsStringAsync();
}

如果你像@Joel Coehoorn那样设置MaxLength = 0或者如果你提到的话忘记MultiLine部分,那么你的文本框被破坏是事实。我希望这篇文章对你有所帮助,尽管你的问题已得到解答。