Answer the question
In order to leave comments, you need to log in
How to update TreeView in real time with data from another thread?
I am writing my own OPC client.
There was a problem which I cannot solve yet.
After connecting, I want to build a tree from the contents of the server. To do this, I wrote a method that recursively roams the server branches and gets information about them. Based on this information, new nodes for the tree are created. The problem is that the construction takes a long time and the form is not active all this time.
I moved the tree construction to a separate thread, but then the nodes in the tree do not appear at all (I am not very friendly with threads yet). I want to achieve an effect in which a separate thread will search for and create new tree nodes, but the nodes that have already been added would immediately be displayed on the form. I just can't figure out how to implement it.
Answer the question
In order to leave comments, you need to log in
I solved this problem.
First, run the method on a new thread:
private void FrOpcBrowser_Shown(object sender, EventArgs e)
{
try
{
currentServer.Connect(serverID);
Text = serverID;
treeView1.Nodes.Clear();
treeView1.Nodes.Add(new TreeNode(serverID));
treeView1.SelectedNode = treeView1.Nodes[0];
TreeNode startNode = treeView1.SelectedNode;
Thread thread = new Thread(delegate () { DoBrowse(startNode, -1); });
thread.Start();
}
catch(Exception)
{
MessageBox.Show("Oops");
Close();
}
}
private void DoBrowse(TreeNode startNode, int depth)
{
try
{
OPCNAMESPACETYPE opcOrgi = currentServer.QueryOrganization();
if (opcOrgi == OPCNAMESPACETYPE.OPC_NS_HIERARCHIAL)
{
//Устанавливем курсор на корневой узел дерева сервера
currentServer.ChangeBrowsePosition(OPCBROWSEDIRECTION.OPC_BROWSE_TO, "");
//Проверяем не является ли выбранный узел корнем сервера
if (startNode.FullPath.Length > serverID.Length)
{
//Если выбранный узел не корень сервера, то получаем полный путь для данного узла
string[] splitpath = startNode.FullPath.Substring(serverID.Length + 1).Split(new char[] { '\t', '\\' });
//Имея полный путь, спускаемся до выбранного узла на сервере
foreach (string n in splitpath)
{
currentServer.ChangeBrowsePosition(OPCBROWSEDIRECTION.OPC_BROWSE_DOWN, n);
}
}
RecurBrowse(startNode, depth);
}
}
catch(Exception)
{
MessageBox.Show("browse error!", "DoBrowse", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
return;
}
private bool RecurBrowse(TreeNode startNode, int depth)
{
try
{
if (depth == 0)
{
return true;
}
currentServer.Browse(OPCBROWSETYPE.OPC_BRANCH, out ArrayList lst);
if (lst == null || lst.Count < 1)
{
return true;
}
foreach(string branch in lst)
{
TreeNode nextNode = new TreeNode(branch);
AddNode(startNode, nextNode);
currentServer.ChangeBrowsePosition(OPCBROWSEDIRECTION.OPC_BROWSE_DOWN, branch);
RecurBrowse(nextNode, depth - 1);
currentServer.ChangeBrowsePosition(OPCBROWSEDIRECTION.OPC_BROWSE_UP, "");
}
}
catch(Exception)
{
MessageBox.Show(this, "browse error!", "RecurBrowse", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return false;
}
return true;
}
private void AddNode(TreeNode parentNode, TreeNode childNode)
{
if (InvokeRequired)
{
Invoke(new Action<TreeNode, TreeNode>(AddNode), new TreeNode[] { parentNode, childNode });
return;
}
parentNode.Nodes.Add(childNode);
}
Well, firstly, look at what lazy adding of nodes is, and access to the UI Thread through Application.Current.Dispatcher
Of course, I'm not special in .net, but most likely you need to follow the principle of semaphores. less likely to shoot yourself in the foot. By analogy with Java, Net has a monitor class and there are analogies of the Java invokeLater, only more flexible.
And the code will be something like the following.
general collection for nodes. The first thread waits for the collection to become free and the thread to wake up or call some update method on that collection. The second thread sherudit and fills the collection and for some values (accumulated 20 values for example) wakes up the first thread or calls the update method in it. In general, you will protect yourself from the stream race.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question