【发布时间】:2021-04-17 21:39:43
【问题描述】:
我正在尝试以 50 毫秒的时间间隔将一批节点异步添加到 TreeView,但我收到一个异常,即集合已被修改。
Collection was modified; enumeration operation may not execute.
我怎样才能防止这种情况发生?
public partial class Form1 : Form
{
private SynchronizationContext synchronizationContext;
private DateTime previousTime = DateTime.Now;
private List<int> _batch = new List<int>();
public Form1()
{
InitializeComponent();
}
private async void button1_Click(object sender, EventArgs e)
{
synchronizationContext = SynchronizationContext.Current;
await Task.Run(() =>
{
for (var i = 0; i <= 5000000; i++)
{
_batch.Add(i);
UpdateUI(i);
}
});
}
public void UpdateUI(int value)
{
var timeNow = DateTime.Now;
if ((DateTime.Now - previousTime).Milliseconds <= 50) return;
synchronizationContext.Post(new SendOrPostCallback(o =>
{
foreach (var item in _batch)
{
TreeNode newNode = new TreeNode($"{item}");
treeView1.Nodes.Add(newNode);
}
}), null);
_batch.Clear();
previousTime = timeNow;
}
}
【问题讨论】:
-
我们在谈论什么样的应用程序(WinForms、WPF 等)?
-
嗨彼得,它是 WinForms。
-
我认为
Dispatcher.CurrentDispatcher会比使用SynchronizationContext更好。你可以使用它的Invoke和BeginInvokemethods 来调度一个在UI线程上运行的方法。
标签: c# loops async-await thread-safety synchronizationcontext