我有一个Windows窗体应用程序和一个类。
该类在不同的线程中触发事件,因此我需要在接收事件的表单中的函数中执行Control.InvokeRequired
和Control.Invoke()
的代码。
是否可以在类上进行所有线程处理,这样我就不需要在表单中执行Invoke()
,并假设所有即将发生的事件已经在同一个线程上?
我正在考虑的解决方案,我不喜欢,是在类的构造函数中启动虚拟控件,或者传递对类中表单的引用,并检查InvokeRequired
。
还有其他可能的解决方案吗?
答案 0 :(得分: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