Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/14.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
Vb.net .net添加处理程序多线程_Vb.net_Add_Handler_Cross Thread - Fatal编程技术网

Vb.net .net添加处理程序多线程

Vb.net .net添加处理程序多线程,vb.net,add,handler,cross-thread,Vb.net,Add,Handler,Cross Thread,我在这里用vb中的多线程使自己陷入了困境。 我有一个工作程序,我使用的addhandler地址订阅4个事件,并指向主窗体上的函数。我有4个独立的函数,除了每个函数的4个唯一地址之外,它们都做完全相同的事情。它们需要调用,在函数顶部调用我的委托,然后函数所做的就是生成另一个进程的线程并将处理交给它 当我使用这个程序并处理来自其中一个订阅的事件时,一切都很好。当我开始处理2的时候,速度会慢一点,然后我处理4的时候,它就真的阻塞了。当我生成每个订阅的事件时,它们都会同时发生,因此windows会同时收

我在这里用vb中的多线程使自己陷入了困境。 我有一个工作程序,我使用的addhandler地址订阅4个事件,并指向主窗体上的函数。我有4个独立的函数,除了每个函数的4个唯一地址之外,它们都做完全相同的事情。它们需要调用,在函数顶部调用我的委托,然后函数所做的就是生成另一个进程的线程并将处理交给它

当我使用这个程序并处理来自其中一个订阅的事件时,一切都很好。当我开始处理2的时候,速度会慢一点,然后我处理4的时候,它就真的阻塞了。当我生成每个订阅的事件时,它们都会同时发生,因此windows会同时收到4个请求,并假定将它们排队并处理它们。这是我的应用程序中的一个瓶颈

我想知道是否有可能这样做,就是将订阅的事件(即我所做的添加处理程序地址为to)指向另一个线程,并跨多个线程异步处理引发的事件,因此我不会在一个线程上排队。我知道这是可能的,因为我可以运行两个应用程序并处理其中两个应用程序之间的事件,这样可以提高性能,如果我运行4个单独的应用程序也是如此

我知道我有所有正确的部分,只是不能按照正确的顺序把它们拼凑起来

Public Class MainUI

Public Sub start()
    AddHandler MyEvent.EventHasHappened, AddressOf OnthisUI
    AddHandler ThreadedRoutine.Callback, AddressOf HandedBAck
End Sub

Delegate Sub On_thisUI()
Public Sub OnthisUI()

    If InvokeRequired Then
        'create a pointer to this function
        Dim MyDel As New On_thisUI(AddressOf OnthisUI)
        'call this same function from this thread
        Dim Eventargs() As Object = {sender, e}
        Invoke(MyDel, Eventargs)
        Return
    End If

    Dim Handmeoff As New ThreadedRoutine
    Dim newThread As New System.Threading.Thread(AddressOf Handmeoff.handoffexecution)
    newThread.Start()

End Sub

Public Sub HandedBAck()
    ' Update UI in here

End Sub

End Class

Public Class ThreadedRoutine
Public Shared Event Callback()
Public Sub handoffexecution()
    ' Do some work in here
    RaiseEvent Callback()

End Sub
End Class
很抱歉给出了一个粗略的例子,但这非常突出了我目前正在做的事情

myevent.EventHashappen是我希望跨多个线程同时执行的订阅,而不是使用mainUI线程接收事件并在接收到事件时将其输出到其他程序线程

我考虑将Addhandler订阅放在另一个类中,然后像这样调用该类的实例

Public Class Subscribe
Public Sub New()
    AddHandler myevent.eventhashappened, AddressOf HandleMyEvent
End Sub

Public Sub HandleMyEvent()

End Sub 
End Class
Dim MyHandler1 as new Subscribe
Dim MyHandler2 as new Subscribe
Dim MyHandler3 as new Subscribe
Dim MyHandler4 as new Subscribe
然后我可以像这样声明4个侦听器类

Public Class Subscribe
Public Sub New()
    AddHandler myevent.eventhashappened, AddressOf HandleMyEvent
End Sub

Public Sub HandleMyEvent()

End Sub 
End Class
Dim MyHandler1 as new Subscribe
Dim MyHandler2 as new Subscribe
Dim MyHandler3 as new Subscribe
Dim MyHandler4 as new Subscribe
这样行吗

只是想弄清楚我想展示的是什么

eventOccessed是我在开始时添加的钩子。外部事件会定期引发此问题(为清楚起见,目前代码中未显示)

然后,这会在ui中触发一个例程,该例程生成 处理事件、执行某些处理(也未显示)的新进程启动线程,当线程完成时,它会使用一些要更新的参数调用ui(同样未显示)

我希望的行为是启动初始钩子,并在另一个不是UI的线程上处理它。我总是必须在某个时候返回UI,但我想清除管道中的第一个瓶颈


关于

您是否有可以发布的代码?干杯,欢迎来到Stack Overflow!请编辑您的问题,以包括一个,这样我们可以更好地了解正在发生的事情,也许能够自己测试它。非常感谢。需要记住的一件事是,在辅助线程上执行代码通常没有问题。以这种方式处理事件意味着有必要封送对UI线程的调用。在UI线程上执行代码的要求仅适用于控件的访问成员。如果您有一个方法可以运行10分钟,并在这里和那里更新一些
标签
,那么您只需要封送回UI线程来更新
标签
。代码的其余部分将在后台线程上愉快地执行。听起来你可能正在UI线程上执行不需要的代码。听起来这个程序正在遭受第三个最常见的线程问题,firehose bug。工作线程可以为UI线程提供大量工作,显示工作结果。线程越多,结果越多,UI线程越是陷入试图保持的困境。这会很快变得很糟糕,每秒调用超过1000次,UI线程开始燃烧100%的内核。现在它完全没有反应了。这个比率远远高于人眼所能观察到的,所以这只是白费力气。你必须故意降低调用速度来解决这个问题。检查问题是否存在的一个简单方法是在调用之前添加Thread.Sleep(15)。