C#:使用虚拟机初始化事件处理程序 [英] C#: Initializing an event handler with a dummy
问题描述
我已经看到这样一些代码:
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屋!