gpt4 book ai didi

c# - 安全地从线程中引发事件

转载 作者:行者123 更新时间:2023-12-03 13:22:41 24 4
gpt4 key购买 nike

我在从非 UI 线程引发的事件方面遇到一些问题,因为我不希望必须在添加到 Form1 中的线程的每个事件处理程序上处理 If me.invokerequired。

我确定我已经在某处阅读过如何使用委托(delegate)事件(在 SO 上),但我找不到它。

Public Class Form1

Private WithEvents _to As New ThreadedOperation

Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button.Click
_to.start()
End Sub

Private Sub _to_SomthingHappend(ByVal result As Integer) Handles _to.SomthingHappend
TextBox.Text = result.ToString //cross thread exception here
End Sub

End Class

Public Class ThreadedOperation

Public Event SomthingHappend(ByVal result As Integer)
Private _thread As Threading.Thread

Public Sub start()
If _thread Is Nothing Then
_thread = New Threading.Thread(AddressOf Work)
End If
_thread.Start()
End Sub

Private Sub Work()
For i As Integer = 0 To 10
RaiseEvent SomthingHappend(i)
Threading.Thread.Sleep(500)
Next
End Sub

End Class

最佳答案

您从 Control 派生了您的类。有点不寻常,但如果控件实际上托管在窗体上,则可以使用 Me.Invoke() 来编码调用。例如:

  Private Delegate Sub SomethingHappenedDelegate(ByVal result As Integer)

Private Sub Work()
For i As Integer = 0 To 10
Me.Invoke(New SomethingHappenedDelegate(AddressOf SomethingHappenedThreadSafe), i)
Threading.Thread.Sleep(500)
Next
End Sub

Private Sub SomethingHappenedThreadSafe(ByVal result As Integer)
RaiseEvent SomthingHappend(result)
End Sub

如果此类对象实际上并未托管在表单上,​​则需要传递对表单的引用,以便它可以调用 Invoke():
  Private mHost As Form

Public Sub New(ByVal host As Form)
mHost = host
End Sub

并使用 mHost.Invoke()。或 BeginInvoke()。

本书的最后一个技巧是使用你的主启动窗体作为同步对象。这并不完全安全,但在 99% 的情况下都有效:
  Dim main As Form = Application.OpenForms(0)
main.Invoke(New SomethingHappenedDelegate(AddressOf SomethingHappenedThreadSafe), i)

请注意,WF 中有一个错误会阻止 OpenForms() 在动态重新创建打开的表单时准确跟踪它们。

关于c# - 安全地从线程中引发事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/292715/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com