Svi*_*ish 5 c# multithreading event-handling
我在某些地方看到过这种代码:
public event SomeEventHandler SomeEvent = (s, e) => { };
Run Code Online (Sandbox Code Playgroud)
这是一种推荐的做事方式吗?它解决了什么,是否有任何值得注意的副作用?我还需要做空检查吗?或者这正是我不必再做的了?垃圾收集仍然可以正常工作吗?
例如:
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));
}
Run Code Online (Sandbox Code Playgroud)
我可以将第一行更改为:
private PropertyChangedEventHandler propertyChanged = (s, e) => { };
Run Code Online (Sandbox Code Playgroud)
然后跳过OnPropertyChanged方法中的空值检查?如果我然后跳过空检查我可以跳过锁吗?如果是这样会给我这个:
protected void OnPropertyChanged(string propertyName)
{
propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
Run Code Online (Sandbox Code Playgroud)
考虑初始化时,这是否安全?还是有一些我错过的副作用?
虽然您不需要进行无效性检查,但如果您真的想尝试使事件成为线程安全的,那么您仍然需要在锁中获取它:
protected void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler;
lock (propertyChangedLock)
{
handler = propertyChanged;
}
handler(this, new PropertyChangedEventArgs(propertyName));
}
Run Code Online (Sandbox Code Playgroud)
否则,你可能不获取最新的价值-如果在不同的线程被添加的事件处理程序,理论上你就可以永远引发事件而没有调用新的处理程序.在实践中,我相信你几乎总是会在没有锁的情况下逃脱,但在记忆模型方面,你应该有一些围栏.
我个人建议你不要试图使事件线程安全.
| 归档时间: |
|
| 查看次数: |
4211 次 |
| 最近记录: |