I've been working through my first project and have had a great deal a valuable help from the guys on SO but now I'm stuck again...
我一直在完成我的第一个项目,并且从那些人那里获得了很多有价值的帮助,但现在我再次陷入困境......
The below sub is used to add treenodes to a treeview, excluding certain filetypes/names, upon addition of new data
以下子用于在添加新数据时将treenode添加到树视图中,不包括某些文件类型/名称
Sub DirSearch(ByVal strDir As String, ByVal strPattern As String, ByVal tvParent As TreeNodeCollection)
Dim f As String
Dim e As String
Dim tvNode As TreeNode
Dim ext() As String = strPattern.Split("|"c)
Try
For Each d In Directory.GetDirectories(strDir)
If (UCase(IO.Path.GetFileName(d)) <> "BACKUP") And (UCase(IO.Path.GetFileName(d)) <> "BARS") Then
tvNode = tvParent.Add(IO.Path.GetFileName(d))
For Each e In ext
For Each f In Directory.GetFiles(d, e)
If (UCase(IO.Path.GetFileName(f)) <> "DATA.XLS") And (UCase(IO.Path.GetFileName(f)) <> "SPIRIT.XLSX") Then
tvNode.Nodes.Add(IO.Path.GetFileName(f))
End If
Next
Next
DirSearch(d, strPattern, tvNode.Nodes)
End If
Next
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
I'm now getting a Action being performed on this control is being called from the wrong thread. Marshal to the correct thread using Control.Invoke or Control.BeginInvoke to perform this action.
error on the following line
我现在正在从错误的线程调用正在执行此控件的Action。使用Control.Invoke或Control.BeginInvoke对正确的线程进行Marshal来执行此操作。以下行中的错误
tvNode = tvParent.Add(IO.Path.GetFileName(d))
tvNode = tvParent.Add(IO.Path.GetFileName(d))
Obviously i understand its to do with 'threading' and the use of BeginInvoke/Invoke but even after reading the MSDN documentation on the error I have no idea where to start.
显然我理解它与'线程'和使用BeginInvoke / Invoke有关,但即使在阅读错误的MSDN文档之后我也不知道从哪里开始。
This error only occurs if i add a file to the initial directory (which is also the subject of a File System Watcher to monitor new additions).
如果我将文件添加到初始目录(这也是文件系统观察程序的主题,以监视新添加),则只会出现此错误。
Would someone be so kind as to give me an explanation in layman's terms so I may be able to understand.
有人会非常友好地以外行的方式给我一个解释,这样我才能理解。
Thanks :)
谢谢 :)
1 个解决方案
#1
1
This code is being run on a background thread where it's illegal to modify UI elements. The Invoke / BeginInvoke
methods are ways to schedule a piece of code to run on UI thread where elements can be modified. For example you could change your code to the following
此代码在后台线程上运行,修改UI元素是非法的。 Invoke / BeginInvoke方法是调度一段代码以在UI线程上运行的方法,其中可以修改元素。例如,您可以将代码更改为以下内容
Dim action As Action = Sub() tvNode.Nodes.Add(IO.Path.GetFileName(f))
tvNode.TreeView.Invoke(action)
This code will take the delegate instance named action
and run it on the UI thread where edits to tvNode
are allowed
此代码将获取名为action的委托实例,并在允许对tvNode进行编辑的UI线程上运行它
Fixing the earlier Add
call is a bit trickier because there is no Control
instance on which we can call BeginInvoke
. The signature of the method will need to be updated to take a Dim control as Control
as a parameter. You can pass in the TreeView
for that parameter if you like. Once that is present the first Add
can be changed as such
修复早期的Add调用有点棘手,因为没有可以调用BeginInvoke的Control实例。需要更新方法的签名以将Dim控件作为Control作为参数。如果您愿意,可以为该参数传入TreeView。一旦存在,第一个Add就可以这样改变
Dim outerAction As Action = Sub() tvNode = tvParent.Add(IO.Path.GetFileName(d))
control.Invoke(outerAction)
#1
1
This code is being run on a background thread where it's illegal to modify UI elements. The Invoke / BeginInvoke
methods are ways to schedule a piece of code to run on UI thread where elements can be modified. For example you could change your code to the following
此代码在后台线程上运行,修改UI元素是非法的。 Invoke / BeginInvoke方法是调度一段代码以在UI线程上运行的方法,其中可以修改元素。例如,您可以将代码更改为以下内容
Dim action As Action = Sub() tvNode.Nodes.Add(IO.Path.GetFileName(f))
tvNode.TreeView.Invoke(action)
This code will take the delegate instance named action
and run it on the UI thread where edits to tvNode
are allowed
此代码将获取名为action的委托实例,并在允许对tvNode进行编辑的UI线程上运行它
Fixing the earlier Add
call is a bit trickier because there is no Control
instance on which we can call BeginInvoke
. The signature of the method will need to be updated to take a Dim control as Control
as a parameter. You can pass in the TreeView
for that parameter if you like. Once that is present the first Add
can be changed as such
修复早期的Add调用有点棘手,因为没有可以调用BeginInvoke的Control实例。需要更新方法的签名以将Dim控件作为Control作为参数。如果您愿意,可以为该参数传入TreeView。一旦存在,第一个Add就可以这样改变
Dim outerAction As Action = Sub() tvNode = tvParent.Add(IO.Path.GetFileName(d))
control.Invoke(outerAction)