我正在开发一个解析器应用程序,用于从已从数据库中提取的DDL文件构建调用树。这个想法是采取大量的这些DDL文件,并确定究竟是什么调用什么。为此,我正在使用.NET TreeView。我对工作的最终输出是这样的:现在在Visual Basic中锁定另一个线程的控件
-Proc1
-Proc2
-Proc3
-Proc4
-Proc2
-Proc3
-Proc3
-Proc4
,我所有的解析工作正常。虽然这个过程非常漫长。因此,我决定将所有重量级处理都移到自己的线程中。一切都按预期工作,直到我需要更新我的TreeView。我试图保留单独线程上的所有实际更新逻辑,并只更新TreeView。但是,尽管我的主要形式是SyncLocked,但在尝试访问该树时仍遇到异常。
我在网上发现了很多例子,展示了如何使用Delegates进行线程安全访问,但不幸的是,它们都对我的需求有点简单。大多数只是显示如何设置文本属性。正如我前面提到的那样,我试图在工作线程上尽可能多地进行处理,并且只调用相应的TreeView方法来更新,因为此过程可能会很长时间(一次解析和显示数百个过程) 。
是否有一个很好的方法来做到这一点,或者我应该把我的肿块和我的整个依赖树传递回我的主窗体?
这是我目前用来显示第一级依赖关系的代码。请记住,这最终将是递归的(目前在“搞不定”模式),这就是为什么我要保持它关闭UI线程:
Public Sub updateTreeView()
Dim arrNodeList As ArrayList
Dim childNode As clsProcedureNode
Dim currentNode As clsProcedureNode
Dim intChildIndex As Integer
Dim intNodeListIndex As Integer
Dim treeView As TreeView
//Lock main form
SyncLock mMainForm
//Check that we are actually running on a seprate thread
If mMainForm.InvokeRequired() = True Then
//Call delegate to get handle to TreeView
treeView = mMainForm.Invoke(mGetTreeViewDelegate)
//Add Parsed array to main form TreeView
For intNodeListIndex = 0 To mProcedureNodes.Length - 1
//Get current node and its child list
currentNode = mProcedureNodes(intNodeListIndex)
arrNodeList = currentNode.getProcsCalled()
//Add node and all children to TreeView
With treeView
.BeginUpdate()
.Nodes.Add(currentNode.getName())
For intChildIndex = 0 To arrNodeList.Count
childNode = arrNodeList.Item(intChildIndex)
.Nodes(intNodeListIndex).Nodes.Add(childNode.getName())
Next
.EndUpdate()
End With
Next
End If
End SyncLock
End Sub
你不需要在UI线程上操作树视图吗?您将树视图拉出主窗体,然后将其填充到线程中。我认为你需要将数据传递回UI线程,然后将其填充到那里。 – ChrisWue 2011-03-18 22:43:55
这实际上是我想要避免的。该过程分两步进行。解析DDL文件,然后构建树。由于我正在使用的数据集非常大且具有递归性质,因此我正尝试执行脱机线程树,以便在填充树时UI不会挂起。 – phobos51594 2011-03-18 22:58:58