为什么在通过ListView进行预处理并使用GetStringAsync时冻结GUI?

时间:2015-11-11 22:45:30

标签: c# json multithreading listview httprequest

我正在使用foreach来浏览其项目是从XML文件加载的ListView。然后我正在使用项目名称到我的网页进行异步HTTPRequest以获取JSON字符串,到目前为止它的效果非常好。

 HttpClient client = new HttpClient();

 foreach (ListViewItem item in lV_Items.Items)
  {
   JObject o = JObject.Parse(client.GetStringAsync("http://000.000.000/?item=" + HttpUtility.UrlEncode(item.Text)).Result);
  }

然后我将JSON中的新值编辑为项目SubItem

string amount= (string)o["amount"];
item.SubItems[1].Text = amount;

我在计时器中运行此代码,每分钟重复一次。然而,即使我阅读了很多关于例如ListView.BeginUpdate或将HTTPRequest放在另一个线程中的事情,我几天都在努力进行性能优化。首先,我不太明白为什么GUI在做foreach时会冻结。鉴于异步HTTP请求不在主线程上工作(至少我希望这是针对异步代表的),它不应该冻结请求。编辑SubItems的操作也应该非常快,特别是因为List中只有大约10个项目。

我想过将Items加载到List(动态集合)而不是直接加载ListView。然后我将运行1个定时器,它定期将List发送到另一个Thread,然后Thread刷新列表中的值并将其发送回主窗体。在Mainform中有第二个计时器,它定期将List放入ListView(仅用于可视化)。两个定时器,因为我认为如果将上述两个都放入一个定时器,定时器将等待线程完成,导致仍然冻结应用程序。

我想这是一个想法,但是有很多不透明的工作已经完成,而且维护/调试可能会更难。我很乐意接受任何有关我应该如何做以及哪些更好的想法。

1 个答案:

答案 0 :(得分:5)

执行client.GetStringAsync(...).Result时,阻止直到GetStringAsync完成,这违背了使用异步方法的目的。您应该使用await代替:

string json = await client.GetStringAsync("http://000.000.000/?item=" + HttpUtility.UrlEncode(item.Text));
JObject o = JObject.Parse(json);

(请注意,您需要制作方法async