我正在阅读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();
});
}
}
答案 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部分,那么你的文本框被破坏是事实。我希望这篇文章对你有所帮助,尽管你的问题已得到解答。