代码之家  ›  专栏  ›  技术社区  ›  Charles Y.

使用addhandler时是否需要输入writelock?

  •  1
  • Charles Y.  · 技术社区  · 15 年前

    使用readwritelockslim支持多线程时,使用addhandler时是否需要输入writelock?

    以下两个例子有助于说明我的观点:

    AddHandler ClassInstance.Event, New EventHandler(AddressOf Me.Method)  
    

    -或

    Me.ReaderWriterLockSlimInstance.EnterWriteLock()
    AddHandler ClassInstance.Event, New EventHandler(AddressOf Me.Method)  
    Me.ReaderWriterLockSlimInstance.ExitWriteLock()
    
    1 回复  |  直到 15 年前
        1
  •  2
  •   Marc Gravell    15 年前

    它可能取决于事件;例如,如果您使用由C通过“类似字段的事件”写入的dll中的事件,即。

    public event EventHandler SomeEvent; // synchronized
    

    (是的,我知道你问过关于vb的问题;我在下面解释这个…)

    然后(根据C语言规范),这是自动同步的,因此不存在多线程问题(在这里,委托是不可变的,这有助于解决这个问题)。然而,即使在同一个库中,非类字段事件也可能 同步-即

    private EventHandler myField;
    public event EventHandler SomeEvent { // not synchronized
        add { myField += value; }
        remove { myField -= value; }
    }
    

    我知道你问过关于vb…但你问的是关于vb的 消费品 . 我的观点是,这取决于 出版商 .

    因此,如果您无法控制发布服务器,则建议手动同步声音 如果 您认为这个场景存在线程风险(在大多数情况下,不需要同步;但是如果您知道这是一个线程区域,那么同步是明智的)。

    还要注意,当 饲养 事件是要拍摄快照:

    protected virtual void OnSomeEvent() {
        EventHandler handler = SomeEvent; // assume the "field-like" version
        if(handler!=null) handler(this, EventArgs.Empty);
    }
    

    我的观点 在这里 从理论上讲,用户是否有可能接收事件 即使他们认为已经退订了 ,因此,如果极端情况下您可能希望手动处理这一问题,可以在某个地方保留一个标志(或者只保留异常处理)。


    根据要求,最后一个代码片段在vb中(通过reflector)进行比较:

    Protected Overridable Sub OnSomeEvent()
        Dim handler As EventHandler = Me.SomeEvent
        If (Not handler Is Nothing) Then
            handler.Invoke(Me, EventArgs.Empty)
        End If
    End Sub