Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 创建新线程时将类作为参数传递_.net_Vb.net_Multithreading_Thread Safety - Fatal编程技术网

.net 创建新线程时将类作为参数传递

.net 创建新线程时将类作为参数传递,.net,vb.net,multithreading,thread-safety,.net,Vb.net,Multithreading,Thread Safety,简而言之,我试图将一个类作为参数传递给另一个由不同线程拥有的方法。这是我的代码的简化: Friend Sub SplitFile(ByVal fileSplitterSettings As FileSplitterSettingsObject) Dim _threadSplitFile As New System.Threading.Thread(Sub() Thread_SplitFile_Start(fileSplitterSettings))

简而言之,我试图将一个类作为参数传递给另一个由不同线程拥有的方法。这是我的代码的简化:

Friend Sub SplitFile(ByVal fileSplitterSettings As FileSplitterSettingsObject)
        Dim _threadSplitFile As New System.Threading.Thread(Sub() Thread_SplitFile_Start(fileSplitterSettings))          
        _threadSplitFile.Start()
End Sub
线程1正在调用SplitFile(),该线程创建线程2,传入一个在线程1中实例化的对象,作为将在线程2上下文下运行的方法的参数

但是,每当我尝试访问线程2下运行的方法Thread\u SplitFile\u Start中的filesplittersetingsobject时,我都会收到一个错误,指出它属于另一个线程

我知道Dispatcher.Invoke()以及如何使用它来运行、读取和更改其他线程的方法和对象,但我不确定如何在这里实现它。我可以在Thread_SplitFile_Start中线程2的上下文中创建该类的新实例,并对Thread_SplitFile_Start中的每个属性使用Dispatcher.Invoke(),以便将值从线程1上下文中的FileSpliterSettings复制到线程2上下文中的新实例,但这似乎有些过分,我正在寻找一个更简单的替代方案

如果需要任何其他信息,我将乐意提供

任何帮助或建议都将不胜感激

编辑:

由于传递诸如整数、字符串等基本类型可以很好地工作,所以我认为传递一个结构类型会起作用,但这似乎也不起作用

编辑:

这就是我正在一起工作的这个班。它是我创建的,因此我可以更改它所需的任何更改:

Namespace Classes

Friend NotInheritable Class FileSplitterSettingsObject
区域“枚举” 末端区域 区域“财产” 末端区域 结束命名空间

我很抱歉没有在前面澄清这一点,但我可以在线程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,以便访问它们的属性。我知道我可以创建一个类型字符串列表,这可能会起作用,但如果知道我正在尝试做的事情将来是否可以完成,那就太好了(例如,对于同时设置了多个属性的对象,不希望创建一组基于基元类型的自定义属性来传递信息)

这可能太简单了(我没有要测试的对象),但我认为。用代码调用将如下所示:

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个线程,这将依次等待主线程执行(因为FilePlitterSettings不是线程安全的)。如果我是您,我会考虑重新设计。可能:

  • 在线程安全类(例如,您创建的类)中传递您需要的设置,即使这只是FilePlitterSettings之上的一个外观

  • 在此线程中创建FilePlitterSettings对象,然后

  • 执行。在同一线程中从这里开始


  • 然后-您就可以使用多线程,不需要干扰调度程序。同样,这可能太简单了,而且我不知道您的环境/限制。希望至少能为您提供一些可玩的东西!

    在与@Brian Saunders合作后,我决定最好使用通用字符串数组来解决这个问题一些属性。

    传递类或实例?看起来更像后者。线程1中声明的类的实例我收到一个错误,说明…您可以粘贴该错误吗?调用线程无法访问该对象,因为它是由另一个线程拥有的:引用FileSpliterSettingsObject感谢Brian提供的信息。我对您的f有一个问题第一块代码。在我的项目中创建线程2时,只有一个线程正在运行,主线程是在程序启动时运行的。是否调用Dispatcher.Invoke()如果在线程2运行之前的所有内容都是在线程1的上下文中运行的,请更改任何关于线程2运行方式的内容。此外,我编辑了我的原始帖子,以包含该类以及一些附加信息。请参阅-我认为ListBoxItem导致了您的hearburn(因为它是一个愚蠢的UI元素,UI元素可能属于UI线程?).仅仅为那些fileNameSuffix值创建自己的字典会是一个巨大的痛苦吗?但是,等等,这不是你真正的问题,是不是…对不起。好的。我一直在想。调用是一种“阻止”Thread2的方法,这样Thread1就可以起作用了(例如-你的UI将在这段时间内“冻结”)。理想情况下,我想你会将UI冻结几微秒,以更新ListBoxItem。是否如此接近?我原以为调用基本上是“询问”一个特定线程在其上下文下运行一个特定方法。也就是说,线程1可以要求线程2运行一个方法,然后按照其愉快的方式运行。但除此之外,FileNameSuffixes不必是字典。它可以是ItemCollection或ListBoxItem数组(所有这些都不起作用)简言之,我只是在寻找一种将包含信息的类传递给另一个线程的方法。如果您知道一种更简单的方法,我很高兴听到您的回答:)我认为您完全正确(只是您正在等待另一个线程“回答”,然后再继续)。顺便说一句,对于你的实际问题(假设你不想使用Invoke),可以试试字典。ItemCollection和ListBoxItem都是UI控件(例如,您传递的是指向windows控件的指针,而不是“数据”)。因此,如果列表框是string/string,则可以使用Dictionary(string,string)而不是ListBoxItem.Content…我想我可以这样做,但这只是因为ListBoxItem的Content属性是字符串。如果我想传递一个UI控件来提取它的属性呢?比如说,我想要p
    For i As Integer = 0 To lbSuffixes.Items.Count - 1
            lbSuffixesItemsList.Add(New ListBoxItem With {
                                                             .Content = CType(lbSuffixes.Items(i), ListBoxItem).Content
                                                         })
    Next
    
    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)