【发布时间】:2015-11-11 22:45:30
【问题描述】:
我正在使用 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 放在另一个线程中的信息,但几天以来我一直在为性能优化而苦苦挣扎。首先,我不太明白为什么在执行 foreach 时 GUI 会冻结。鉴于异步 HTTP 请求不在主线程上完成工作(至少我希望这是异步的代表),它不应该冻结请求。此外,编辑 SubItems 的操作应该很快,特别是因为 List 中只有大约 10 个项目。
我考虑将 Items 直接加载到 List(动态集合)而不是 ListView 中。然后我将运行 1 个计时器,它定期将列表发送到另一个线程,然后线程刷新列表中的值并将其发送回主窗体。在 Mainform 中有第二个计时器,它定期将 List 放入 ListView(仅用于可视化)。两个计时器,因为我认为如果将上述两个都放在一个计时器中,计时器将等待线程完成,导致仍然冻结应用程序。
我想这是一个想法,但是已经完成了很多不透明的工作,并且可能会更难维护/调试。任何关于我应该如何做以及什么会更好的想法都将不胜感激。
【问题讨论】:
-
您在异步方法上调用
.Result,这意味着它将阻塞。由于这发生在 UI 中,这就是它冻结的原因 - 你并没有真正进行异步调用。我建议使用后台工作线程,或者在 UI 中重做您的方法以真正利用 async/await。也许是您调用(和等待)的第二种方法,它执行 foreach 并进行网络调用。 -
在异步方法上调用
.Result是邪恶的...... :) -
我花了这么长时间,但最后程序运行没有冻结。只因为一个字。非常感谢大家!
标签: c# json multithreading listview httprequest