【发布时间】:2020-09-29 21:35:27
【问题描述】:
我正在尝试使用 WPF 以一种 UI 不会冻结的方式将项目添加到 DataGrid。
背景: 我有一个 IP 地址列表。使用这些 IP 地址,应确定更多信息,例如平。这意味着,我会遍历 IP 列表的每一项,根据 IP 确定数据并将结果插入到新列表中。这个新列表的内容应该显示在 DataGrid 中。
现在是这样,大约有 4000 个 IP。估计每秒大约有 15 个条目将添加到 DataGrid 列表中。但是,只有在一个列表中的所有项目都已处理并添加到新列表中后,才会显示该列表。
我的目标是让它看起来像这样: https://www.youtube.com/watch?v=xWC1GvfCI0I
您是否知道如何最好地解决这个问题?这是我尝试的最后一种方式:
public void Get()
{
Task.Run(() =>
{
using (var client = new WebClient())
{
var ips = client.DownloadString("http://monitor.sacnr.com/list/masterlist.txt");
using (var reader = new StringReader(ips))
{
for (string ip = reader.ReadLine(); ip != null; ip = reader.ReadLine())
{
this.Servers.Add(this._sacnr.GetServerProperties(ip));
}
}
}
});
}
谢谢。
【问题讨论】:
-
好的,我现在明白你的意思了,你希望 UI 与你的 get 函数同时更新,也就是说,datagrid 在检索值时应该自动更新,如附加的 YouTube 链接中所示。您需要使用 IProgress 接口。 @N.Dogac 已经在上面发布了一个链接。我现在会删除我的答案
-
我现在尝试这样做:
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => this.Get()));但它仍然冻结。我保留了 Get() 方法。我是不是理解错了? -
使您的方法异步并尝试在 DownloadStringAsync 或 ReadlineAsync 上等待,这应该可以解决问题。或者只是等待 Task.run()。我会尝试所有 3 个选项,看看哪个最适合。
-
如果你想像在视频中一样更新列表,我会绑定到 ObservableCollection 而不是常规列表,然后将项目循环添加到它。这将导致 DataGrid 的平滑更新,ObservableCollection 默认实现 InotifyProperty。