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

本文关键字:预处理 GUI 冻结 GetStringAsync ListView 为什么 | 更新日期: 2023-09-27 18:21:31

我使用foreach浏览ListView,它的项是从XML文件加载的。然后,我在我的网页上使用项目名称进行异步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请求不在主线程上完成它的工作(至少我希望这是异步所代表的),它不应该在请求上冻结。此外,编辑子项目的操作应该非常快,特别是因为列表中只有大约10个项目。

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

我想这是一个想法,但还有很多不透明的工作要做,维护/调试可能会更困难。任何关于我应该如何做以及什么会更好的想法都将不胜感激。

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

当您执行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