相关疑难解决方法(0)

C#事件和线程安全

UPDATE

从C#6开始,这个问题的答案是:

SomeEvent?.Invoke(this, e);
Run Code Online (Sandbox Code Playgroud)

我经常听到/阅读以下建议:

在检查事件之前,请务必复制事件null并将其触发.这将消除线程的潜在问题,其中事件变为null位于您检查null和触发事件的位置之间的位置:

// Copy the event delegate before checking/calling
EventHandler copy = TheEvent;

if (copy != null)
    copy(this, EventArgs.Empty); // Call any handlers on the copied list
Run Code Online (Sandbox Code Playgroud)

更新:我从阅读中了解到这可能还需要事件成员的优化,但Jon Skeet在他的回答中指出CLR不会优化副本.

但同时,为了解决这个问题,另一个线程必须做到这样的事情:

// Better delist from event - don't want our handler called from now on:
otherObject.TheEvent -= OnTheEvent;
// Good, now we can be certain that OnTheEvent will not run...
Run Code Online (Sandbox Code Playgroud)

实际的顺序可能是这种混合物:

// Copy the event delegate before checking/calling
EventHandler copy …
Run Code Online (Sandbox Code Playgroud)

c# events multithreading

230
推荐指数
6
解决办法
8万
查看次数

在事件调度之前检查null ...线程安全吗?

让我感到困惑的东西,但从来没有引起任何问题......推荐的事件发送方式如下:

public event EventHandler SomeEvent;
...
{
    ....
    if(SomeEvent!=null)SomeEvent();
}
Run Code Online (Sandbox Code Playgroud)

在多线程环境中,此代码如何保证另一个线程不会更改SomeEvent检查null和事件调用之间的调用列表?

c# events multithreading

35
推荐指数
3
解决办法
3万
查看次数

哪个是调用事件委托的更好方法?

private void NotifyFreeChannelsChanged() //1.
{
    if (FreeChannelsChanged != null)
    {
        FreeChannelsChanged(this, null);
    }
}

private void NotifyFreeChannelsChanged() //2.
{
    NotifyCollectionChangedEventHandler h = FreeChannelsChanged ;
     if (h != null)
         h(this, e);
}
Run Code Online (Sandbox Code Playgroud)

出于这些更好,为什么.或者它只是一个额外的检查.不是一个主要的区别.

c# events event-handling

7
推荐指数
1
解决办法
107
查看次数

是否有任何理由在提升之前将事件分配给局部变量?

我经常看到如下代码,并想知道是否有任何理由为事件使用局部变量,而不仅仅是使用事件本身.在那儿?

var handler = OnQueryComplete;
if (handler != null)
    handler(this, new RepositoryEventArgs<T>(results));
Run Code Online (Sandbox Code Playgroud)

.net c# events

3
推荐指数
1
解决办法
578
查看次数

标签 统计

c# ×4

events ×4

multithreading ×2

.net ×1

event-handling ×1