0

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

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

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

我不喜欢的我正在考虑的解决方案是在类的构造函数中启动一个虚拟控件,或者传递对类中表单的引用,然后进行检查InvokeRequired

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

4

1 回答 1

1

一般来说,一个类不应该涉及 UI 实现细节。它很可能用于在另一个线程上引发事件无关紧要的场景。在这种情况下,您当然不想编组。你也不知道要编组什么。

有一种很好的方法可以通过 ISynchronizeInvoke 接口在 Winforms 中解耦,FileSystemWatcher.SynchronizingObject 就是一个很好的例子。该属性允许应用程序选择是自行处理编组还是留给 FSW 来完成。在带有 Foo 事件(VS2010 语法)的示例类中,您使它看起来像这样:

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
于 2013-02-23T02:39:58.363 回答