我已经学习了一些关于如何创建custem事件访问器的教程。这是我的代码:
event ControlNameChangeHandler IProcessBlock.OnControlNameChanged
{
add
{
lock (ControlNameChanged)
{
ControlNameChanged += value;
}
}
remove
{
lock (ControlNameChanged)
{
ControlNameChanged -= value;
}
}
}
当代码在添加元素中达到lock(ControlNameChanged)
时,没有任何反应。代码不再运行。但是我的申请仍然有效。它不冻结或什么的。
出了什么问题?
答案 0 :(得分:13)
不知何故,其他人持有锁。您不应该使用多播委托实例或事件来进行锁定,也不应该使用公共成员,因为您无法控制谁在锁定以及何时锁定。
因此我会使用一个单独的锁定对象:
private readonly object controlNameChangedSync = new object();
event ControlNameChangeHandler IProcessBlock.OnControlNameChanged
{
add
{
lock (controlNameChangedSync)
{
ControlNameChanged += value;
}
}
remove
{
lock (controlNameChangedSync)
{
ControlNameChanged -= value;
}
}
}
注意:在委托上执行+=
或-=
时,对事件的引用会发生变化。
答案 1 :(得分:8)
您的代码等同于
event ControlNameChangeHandler IProcessBlock.OnControlNameChanged {
add {
try {
Monitor.Enter(ControlNameChanged);
ControlNameChanged = ControlNameChanged + value;
}
finally {
Monitor.Exit(ControlNameChanged);
}
}
remove {
try {
Monitor.Enter(ControlNameChanged);
ControlNameChanged = ControlNameChanged - value;
}
finally {
Monitor.Exit(ControlNameChanged);
}
}
}
请注意,您退出的对象与您输入的对象不同。这意味着你有一个锁从未被释放,一个锁被释放但从未被取走。您应该将代码更改为:
private object padlock = new object();
event ControlNameChangeHandler IProcessBlock.OnControlNameChanged {
add {
lock (padlock) {
ControlNameChanged += value;
}
}
remove {
lock (padlock) {
ControlNameChanged -= value;
}
}
}
答案 2 :(得分:4)
+=
和-=
运算符更改委托。因此,每次添加和删除方法都锁定在不同的对象上,并且根本没有同步。
现在这不能解释阻塞,但你的问题并不是很清楚实际发生了什么。我希望程序能够“正常”执行并具有竞争条件。