为了简单起见,我试图将一个Class作为参数传递给另一个由不同线程拥有的方法。这是我的代码的简化:
Friend Sub SplitFile(ByVal fileSplitterSettings As FileSplitterSettingsObject)
Dim _threadSplitFile As New System.Threading.Thread(Sub() Thread_SplitFile_Start(fileSplitterSettings))
_threadSplitFile.Start()
End Sub
ThreadFile()正在调用SplitFile(),它创建线程2,传入一个在线程1中实例化的对象,作为将在线程2的上下文中运行的方法的参数。
但是,每当我尝试在线程2下运行的Thread_SplitFile_Start方法中访问 fileSplitterSettingsObject 时,我都会收到一条错误,指出其他线程拥有它。
我知道 Dispatcher.Invoke()以及如何使用它来运行,读取和更改其他线程的方法和对象,但我不确定如何在此处实现它。我可以在Thread_SplitFile_Start中的Thread 2的上下文中创建该类的新实例,并对Thread_SplitFile_Start中的每个属性使用Dispatcher.Invoke(),以便将来自Thread 1的上下文中的fileSplitterSettings的值复制到线程2的上下文中的一个新实例,但这似乎有点矫枉过正,我正在寻找一个更简单的替代方案。
如果需要任何其他信息,我很乐意提供。
非常感谢任何帮助或建议!
编辑:
由于传递原始类型(如整数,字符串等)工作正常,我认为传入一个结构类型会起作用,但这似乎也不起作用。
编辑:
这是我正在使用的这门课程。这是我创建的,所以我需要改变所需的任何更改:
Namespace Classes
Friend NotInheritable Class FileSplitterSettingsObject
Friend Enum FileSavingMode
ModeTogether = 0
ModeSeparate = 1
End Enum
Private _propertyDeleteOriginalFile As Boolean = False
Private _propertyUseCustomSuffixes As Boolean = False
Private _propertyFilenameSuffixes As List(Of ListBoxItem)
Private _propertySavingMode As FileSavingMode = Nothing
Friend Property DeleteOriginalFile As Boolean
Get
Return _propertyDeleteOriginalFile
End Get
Set(value As Boolean)
_propertyDeleteOriginalFile = value
End Set
End Property
Friend Property UseCustomSuffixes As Boolean
Get
Return _propertyUseCustomSuffixes
End Get
Set(value As Boolean)
_propertyUseCustomSuffixes = value
End Set
End Property
Friend Property FileNameSuffixes As List(Of ListBoxItem)
Get
Return _propertyFilenameSuffixes
End Get
Set(value As List(Of ListBoxItem))
_propertyFilenameSuffixes = value
End Set
End Property
Friend Property SavingMode As FileSavingMode
Get
Return _propertySavingMode
End Get
Set(value As FileSavingMode)
_propertySavingMode = value
End Set
End Property
End Class
结束命名空间
我很抱歉没有提前澄清这一点,但我可以访问"大多数"线程2中的这些属性。我唯一无法访问的是 FileNameSuffixes ,它在线程1中设置如下:
For i As Integer = 0 To lbSuffixes.Items.Count - 1
lbSuffixesItemsList.Add(New ListBoxItem With {
.Content = CType(lbSuffixes.Items(i), ListBoxItem).Content
})
Next
我认为它与在线程1中实例化ListBoxItems有关,这就是线程2无法访问它们的原因。基本上,我需要将这些项目传递给线程2,因此我可以访问它们的属性。我知道我可以创建一个String类型的列表,它可能会工作,但是很高兴知道我将来要做的事情是否可以完成(例如,对于同时设置了多个属性的对象,不想基于原始类型创建一堆自定义属性,只是为了传递信息)
答案 0 :(得分:0)
这可能太简单了(我没有你的对象可以测试),但我认为。使用你的代码进行调用看起来像这样:
Dispatcher.Invoke(Sub()
Dim _threadSplitFile As New System.Threading.Thread(Sub() Thread_SplitFile_Start(fileSplitterSettings))
_threadSplitFile.Start()
End Sub)
或者这个:
Dim _threadSplitFile As New System.Threading.Thread(Sub() Thread_SplitFile_Start(fileSplitterSettings))
Dispatcher.Invoke(Sub()
_threadSplitFile.Start()
End Sub)
...取决于您收到错误的位置。
但是 - 您正在创建2个线程,这些线程将等待主线程执行(因为fileSplitterSettings不是线程安全的)。如果我是你,我会考虑重新设计。也许:
在线程安全的类中传递您需要的设置(例如 - 您创建的类)。即使这只是fileSplitterSettings
在此主题中创建一个fileSplitterSettings对象,
在同一个帖子中执行.Start。
然后 - 你得到多线程,不需要捣乱调度员。再一次,可能过于简单化了,我不知道你的环境/限制。希望至少能为你提供一些游戏!
答案 1 :(得分:0)
在与@Brian Saunders合作之后,我确定最好只使用通用字符串数组来传递这个麻烦的属性。