我正在尝试更新一个包含大量数据的ListBox
,以保持用户界面(UI)的响应性。
为此,我使用以下代码将数据收集到100个项目的批中,然后将这些批一次性插入到ListBox
中,而不是逐个插入每个项目。代码不能按预期工作,只有在所有项都添加到ListBox
之后,UI才会更新。
public partial class Form1 : Form
{
private SynchronizationContext synchronizationContext;
public Form1()
{
InitializeComponent();
}
private async void button1_Click(object sender, EventArgs e)
{
synchronizationContext = SynchronizationContext.Current;
await Task.Run(() =>
{
ConcurrentDictionary<int, int> batch = new ConcurrentDictionary<int, int>();
int count = 0;
for (var i = 0; i <= 10000; i++)
{
batch[i] = i;
count++;
if (count == 100)
{
count = 0;
UpdateUI(batch);
batch = new ConcurrentDictionary<int, int>();
}
}
});
}
private void UpdateUI(ConcurrentDictionary<int, int> items)
{
synchronizationContext.Post(o =>
{
listBox1.SuspendLayout();
foreach (var item in items)
{
listBox1.Items.Add(item.Value);
}
listBox1.ResumeLayout();
}, null);
}
}
1条答案
按热度按时间ars1skjm1#
您不需要多线程方法来更新UI。您所需要的只是在批量插入过程中通过使用
ListBox.BeginUpdate
和ListBox.EndUpdate
方法暂停ListBox
的绘制:当您在弹性容器中动态加入控件,并且想要防止控件在加入每个新控件时跳来跳去时,就会使用
Control.SuspendLayout
和Control.ResumeLayout
方法。