Worker thread is blocking UI !!!

  • Thread starter Thread starter Gancy
  • Start date Start date
G

Gancy

Hi,
I am trying to add nodes into a treeview control (through recursion)
from a secondary thread. Following is the code snippet

class Test
{
private delegate void ThreadSafeCallback();
private System.Threading.Thread thrMIBTree;
private System.Threading.ThreadStart startMIBTree;

// Class constructor
public Test()
{
startMIBTree = new
System.Threading.ThreadStart(BuildMIBTree);
thrMIBTree = new System.Threading.Thread(startMIBTree);
}

void BuildMIBTree()
{
// This if condition is to allow the marhsalling, so
that the thread which
// created the control actually adds nodes to it.
if (tvwProperties.InvokeRequired)
{
ThreadSafeCallback StdMIBTree = new
ThreadSafeCallback(BuildMIBTree);
tvwProperties.Invoke(StdMIBTree);
}
else
{
objSNMPManager.CompileMibs(this.m_sMIBPath);

foreach (Variables snmpVar in
objSNMPManager.Variables)
AddNode(snmpVar.Oid);
}
}

private void AddNode(string OID)
{
string parentOID = ParentNode(OID);
TreeNode[] nd = tvwProperties.Nodes.Find(parentOID, true);

if (nd.Length == 0)
AddNode(parentOID);

TreeNode newNode = new TreeNode();
newNode.Name = OID;
newNode.Text = GetDescription(OID);

nd = tvwProperties.Nodes.Find(parentOID, true);
nd[0].Nodes.Add(newNode);
}

private void toolButtonProps_Click(object sender, EventArgs e)
{
thrMIBTree.Start();
}
}

What i dont understand is why call to thrMIBTree.Start() is blocking
the UI? any better method to do this?

Thanks
- Gancy
 
Gancy said:
Hi,
I am trying to add nodes into a treeview control (through recursion)
from a secondary thread. Following is the code snippet

class Test
{
private delegate void ThreadSafeCallback();
private System.Threading.Thread thrMIBTree;
private System.Threading.ThreadStart startMIBTree;

// Class constructor
public Test()
{
startMIBTree = new
System.Threading.ThreadStart(BuildMIBTree);
thrMIBTree = new System.Threading.Thread(startMIBTree);
}

void BuildMIBTree()
{
// This if condition is to allow the marhsalling, so
that the thread which
// created the control actually adds nodes to it.
if (tvwProperties.InvokeRequired)
{
ThreadSafeCallback StdMIBTree = new
ThreadSafeCallback(BuildMIBTree);
tvwProperties.Invoke(StdMIBTree);
}
else
{
objSNMPManager.CompileMibs(this.m_sMIBPath);

foreach (Variables snmpVar in
objSNMPManager.Variables)
AddNode(snmpVar.Oid);
}
}

private void AddNode(string OID)
{
string parentOID = ParentNode(OID);
TreeNode[] nd = tvwProperties.Nodes.Find(parentOID, true);

if (nd.Length == 0)
AddNode(parentOID);

TreeNode newNode = new TreeNode();
newNode.Name = OID;
newNode.Text = GetDescription(OID);

nd = tvwProperties.Nodes.Find(parentOID, true);
nd[0].Nodes.Add(newNode);
}

private void toolButtonProps_Click(object sender, EventArgs e)
{
thrMIBTree.Start();
}
}

What i dont understand is why call to thrMIBTree.Start() is blocking
the UI? any better method to do this?

"tvwProperties.Invoke(StdMIBTree)" is causing StdMIBTree to actually do all
the work on the UI thread - that is what it is for!

Build a root node (with subnodes) in the worker thread but don't add it to
the view.
THEN use tvwProperties.Invoke to pass the constructed node back to the UI
thread to actually add it to the view (you'll need another delegate/method).

Alternatively build the tree piece by piece using Invoke to add each node
individually.

Also dont forget to use BeginEdit and EndEdit where appropriate.
 
Also remember that Invoke() blocks until it is complete. If you want to
prevent blocking, use BeginInvoke() and EndInvoke().
 
Jeroen-bart Engelen said:
Also remember that Invoke() blocks until it is complete. If you want to
prevent blocking, use BeginInvoke() and EndInvoke().

True but that's not his problem - he is blocking the worker to do work on
the UI thread when his whole reason for having a worker was that it should
do the work.
 
Back
Top