C#:使用虚拟机初始化事件处理程序 [英] C#: Initializing an event handler with a dummy

查看:95
本文介绍了C#:使用虚拟机初始化事件处理程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经看到这样一些代码:

  public event SomeEventHandler SomeEvent =(s,e)=> ; {}; 

这是推荐的做事方式吗?它解决了什么,它有什么值得注意的副作用?我还要做空检吗?还是正是我不再需要做了什么?垃圾收集是否仍然可以正常工作?






例如:



private $
private readonly object propertyChangedLock = new object();
public event PropertyChangedEventHandler PropertyChanged
{
add
{
lock(propertyChangedLock)
propertyChanged + = value;
}
删除
{
lock(propertyChanged)
propertyChanged - = value;
}
}
protected void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler;
lock(propertyChangedLock)
handler = propertyChanged;

if(handler!= null)
handler(this,new PropertyChangedEventArgs(propertyName));
}

我可以将第一行更改为:

  private PropertyChangedEventHandler propertyChanged =(s,e)=> {}; 

然后在OnPropertyChanged方法中跳过空检查?如果我然后跳过空检,我可以跳过锁吗?如果是这样的话可以给我这样的:

  protected void OnPropertyChanged(string propertyName)
{
propertyChanged这个,新的PropertyChangedEventArgs(propertyName));
}

考虑到初始化时会安全吗?还是有一些我错过的副作用?

解决方案

虽然你不需要做无效检查,如果真的要尝试使事件线程安全,您仍然需要在锁中获取它:

  protected void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler;
lock(propertyChangedLock)
{
handler = propertyChanged;
}
处理程序(这是新的PropertyChangedEventArgs(propertyName));
}

否则,您可能无法获取最新的值 - 如果事件处理程序正在在不同的线程中添加,理论上可以永远提升事件,而不用调用新的处理程序。实际上,我相信你几乎总是没有锁定就会离开,但是在记忆模式中,你应该有一些的围栏。



我个人建议您不要尝试使事件线程安全。


I've seen this sort of code some places:

public event SomeEventHandler SomeEvent = (s, e) => { };

Is that a recommended way of doing things? What does it solve, and does it have any noteworthy side effects? Will I still have to do null checks? Or is that exactly what I don't have to do any more? Will garbage collection still work as it should?


For example:

private PropertyChangedEventHandler propertyChanged;
private readonly object propertyChangedLock = new object();
public event PropertyChangedEventHandler PropertyChanged
{
    add
    {
        lock (propertyChangedLock)
            propertyChanged += value;
    }
    remove
    {
        lock (propertyChanged)
            propertyChanged -= value;
    }
}
protected void OnPropertyChanged(string propertyName)
{
    PropertyChangedEventHandler handler;
    lock (propertyChangedLock)
        handler = propertyChanged;

    if (handler != null)
        handler(this, new PropertyChangedEventArgs(propertyName));
}

Could I change the first line into this:

private PropertyChangedEventHandler propertyChanged = (s, e) => { };

And then skip the null-check in the OnPropertyChanged method? And if I then skip the null-check could I then also skip the lock? If so that would give me this:

protected void OnPropertyChanged(string propertyName)
{
    propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}

Would that be safe when taking the initialization into account? Or are there some side effects I have missed?

解决方案

While you don't need to do the nullity checks, if you really want to try to make the event thread-safe, you still need to fetch it in a lock:

protected void OnPropertyChanged(string propertyName)
{
    PropertyChangedEventHandler handler;
    lock (propertyChangedLock)
    {
        handler = propertyChanged;
    }
    handler(this, new PropertyChangedEventArgs(propertyName));
}

Otherwise you may not be fetching the most recent value - if event handlers are being added in a different thread, you could theoretically raise events forever without ever calling the new handlers. In practice I believe you'll almost always get away without the lock, but in memory-model terms you should have some sort of fence.

Personally I recommend that you don't try to make the events thread-safe.

这篇关于C#:使用虚拟机初始化事件处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆