使所有类事件与构造函数调用线程在同一线程上激发

本文关键字:线程 一线 函数调用 事件 | 更新日期: 2023-09-27 18:00:33

我有一个windows窗体应用程序和一个类。

该类在不同的线程中触发事件,因此我需要在接收事件的窗体中的函数中执行Control.InvokeRequiredControl.Invoke()的代码。

有没有可能让所有的线程处理都发生在类上,这样我就不需要在表单中执行Invoke(),并假设所有即将发生的事件都已经在同一个线程上了?

我正在考虑的解决方案(我不喜欢)是在类的构造函数中启动一个伪控件,或者传递对类中表单的引用,并检查InvokeRequired

还有其他可能的解决方案吗?

使所有类事件与构造函数调用线程在同一线程上激发

通常,类不应该涉及UI实现的详细信息。它很可能用于在另一个线程上引发事件并不重要的场景。在这种情况下,您肯定不想封送。你也不知道该派什么去。

有一种很好的方法可以通过ISynchronizeInvoke接口在Winforms中解除耦合,FileSystemWatcher.SynchronizingObject就是一个很好的例子。该属性允许应用程序选择是处理封送处理本身,还是让FSW来处理

Imports System.ComponentModel
Public Class Example
    Public Event Foo As EventHandler
    Public Property SynchronizingObject As ISynchronizeInvoke
    Protected Sub OnFoo(e As EventArgs)
        If SynchronizingObject IsNot Nothing AndAlso SynchronizingObject.InvokeRequired Then
            SynchronizingObject.BeginInvoke(Sub() RaiseEvent Foo(Me, e), Nothing)
        Else
            RaiseEvent Foo(Me, e)
        End If
    End Sub
End Class

Form类现在可以简单地将自己分配给SynchronizingObject属性,如下所示:

Public Class Form1
    Private WithEvents obj As Example
    Public Sub New()
        InitializeComponent()
        obj.SynchronizingObject = Me
    End Sub
    Private Sub obj_Foo(sender As Object, e As EventArgs) Handles obj.Foo
        '' No marshaling required
        ''...
    End Sub
End Class