Invoke/BeginInvoke
использует PostMessage
внутренне для перенаправления запроса из произвольного потока в поток пользовательского интерфейса. BeginInvoke
будет заполнять вашу очередь сообщений Windows сообщениями, которые должны обрабатываться потоком пользовательского интерфейса, что сопровождается тем фактом, что вы отключаете перерисовку дерева для каждого добавляемого вами узла, вероятно, влияет на вашу способность взаимодействовать с деревом, пока это загрузка.
Одним из вариантов будет пакетирование нескольких обновлений вместе, а затем отправка им обновлений дерева партиями. Поэтому анализируйте файл и обновляйте дерево, используя каждые 100 или некоторое количество узлов, а не 1 за раз.
Обновление: после вашего редактирования для добавления узлов в пакетах я бы предложил следующее.
1 - Вместо использования Invoke
, а не BeginInvoke
, в противном случае очередь заполняется во время обновления дерева, а затем, когда дерево обновляется, следующие тысячи узлов готовы для вставки, что возвращает вас обратно туда, где вы находитесь .
2- Выдержите несколько 100 миллисекунд после вставки каждой партии, чтобы пользовательский интерфейс мог ответить. Вы можете играть с этим, это будет балансировать производительность и пользовательский опыт. Более длительный сон будет более отзывчивым для пользователя, но в конечном итоге загрузка всех данных займет больше времени.
3- Обратите внимание, что ваше текущее пакетное решение пропустит несколько последних узлов, если общее число не кратно 1000
private void AddTreeViewNode(Message msg)
{
TreeNode newNode = new TreeNode(msg.SeqNum);
nodeQueue.Add(newNode);
if (nodeQueue.Count == 1000)
{
var buffer = nodeQueue.ToArray();
nodeQueue.Clear();
Invoke(new Action(() =>
{
treeView1.BeginUpdate();
treeView1.Nodes.AddRange(buffer);
treeView1.EndUpdate();
}));
System.Threading.Thread.Sleep(500);
}
}