【问题标题】:VB.NET RaiseEvent, threadsafe?VB.NET RaiseEvent,线程安全?
【发布时间】:2010-01-08 08:38:02
【问题描述】:

RaiseEvent 线程安全吗?

用 C# 编写

if (event != null)
{
    event.invoke();
}

而且 C# 代码不是线程安全的......

【问题讨论】:

  • 在此上下文中定义“线程安全”。您的意思是,“事件”可以安全使用两次吗?或者,“在当前线程上调用事件是安全的”,或者...?

标签: vb.net thread-safety


【解决方案1】:

如果我需要执行线程安全事件,我会这样写:

Class Test

    Public Event Click(ByVal sender As Object, ByVal e As EventArgs)
    Public Event MouseIn(ByVal sender As Object, ByVal e As EventArgs)

    Private Delegate Sub EventArgsDelegate(ByVal e As EventArgs)
    Private ReadOnly _parent As Control

    Public Sub New(ByVal parent As Control)
        _parent = parent
    End Sub

    Private Sub OnClick(ByVal e As EventArgs)

        If _parent.InvokeRequired Then
            _parent.Invoke(New EventArgsDelegate(AddressOf OnClick), e)
        Else
            RaiseEvent Click(Me, e)
        End If

    End Sub

    Private Sub OnMouseIn(ByVal e As EventArgs)

        If _parent.InvokeRequired Then
            _parent.Invoke(New EventArgsDelegate(AddressOf OnMouseIn), e)
        Else
            RaiseEvent MouseIn(Me, e)
        End If

    End Sub

End Class

然后每当我需要引发事件时,我只使用OnClick(new eventargs(...)) 等。如果您使用Reflector,您可以观察到大多数线程安全控件使用类似的系统。

【讨论】:

  • 您选择代表而不是 _parent.invoke(sub() OnClick(e)) 有什么特别的原因吗?
  • @Baisc:我唯一的原因是 Sub() 作为 lambda 在 vb.net 的所有版本中都不受支持,这是。
  • 好点,做得好 - 出于某种原因,我认为这是一个.Net-4.0 问题。
【解决方案2】:

你宁愿在 C# 中编写:

EventHandler h= myEvent;
if (h!=null)
   h(...);

这避免了明显的问题(即在测试和调用之间取消订阅),但这也不是线程安全的。

调用事件意味着侦听器已准备好处理此事件。这在很大程度上取决于您的具体情况,通常通过使用同步机制来实现。

“线程安全”到底是什么意思?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-24
    • 2018-02-07
    • 1970-01-01
    • 1970-01-01
    • 2014-10-12
    • 2014-01-06
    • 2022-11-21
    • 1970-01-01
    相关资源
    最近更新 更多