我有一个Singleton高度依赖于XML它用作数据库的文件的类.在构造函数中,XML文件被读取,并且FileSystemWatcher正在监视任何进一步的更改.
现在,如果发生任何更改,我将XML再次从文件中读取数据,但此时应该可以访问非类函数,直到XML重新加载文件.
我的问题是我可以简单地this用作同步对象(在重新加载XML文件时)并且不对函数进行任何更改而不是lock对每个函数都进行大的改动吗?
lock(this)最好避免 - 有一个边缘情况,其他一些不相关的代码也可以锁定它,甚至可能导致死锁.
更好的方法是:
private readonly object lockObj = new object();
Run Code Online (Sandbox Code Playgroud)
然后lock(lockObj)- 因为这是私人的,你可以避免这种边缘情况.
另一种策略是将所有数据加载到不可变的封装对象中; 然后你可以通过更新单个引用来交换所有内容; 并且保证引用赋值是原子的.这允许:
private SomeModel model;
public void Refresh() {
SomeModel newModel = new ...
// fully load etc
...
model = newModel;
}
Run Code Online (Sandbox Code Playgroud)
如果你总是拍摄快照,那么效果最好,即代替
var foo = model.Foo;
var bar = model.Bar;
Run Code Online (Sandbox Code Playgroud)
你用:
var snapshot = model;
var foo = snapshot.Foo;
var bar = snapshot.Bar;
Run Code Online (Sandbox Code Playgroud)
从现在开始,我们知道Foo和Bar来自同一型号.
不要lock上this.永远.这是因为您无法控制的代码可能会锁定您的对象并导致很难检测到死锁情况.
相反,使用专用lock对象:
private readonly object locker = new object();
Run Code Online (Sandbox Code Playgroud)
然后:
lock(locker) {
// something something
}
Run Code Online (Sandbox Code Playgroud)
由于locker标记为private,您不必担心锁定对象的对象外部的代码.
| 归档时间: |
|
| 查看次数: |
101 次 |
| 最近记录: |