【发布时间】:2016-07-04 19:24:46
【问题描述】:
我有以下锁定场景,它似乎偶尔会错过一个锁,让 2 个代码实例并行运行。非常感谢您在分析/修复代码方面的帮助。
public delegate void _D(A a);
namespace ExternalDll {
public event _D D;
}
namespace MainSpace {
ExternalDll _externalDll;
public static object lockObj = new object();
public static int counter = 0;
.
.
_externalDll.D += new _D(myEventHandler);
.
.
void myEventHandler(A a) {
lock (lockObj) {
counter++;
// do staff, printouts, etc.
Console.WriteLine("First={0}\n", counter);
// do other staff
Console.WriteLine("Second={0}\n", counter);
}
}
}
ExternalDll 是一个 dll 文件,它接收带有信息 a(类型 A)的网络通信。它以 a 作为输入调用事件 D。
主命名空间将 myEventHandler 注册到由 ExternalDll 触发的事件 D。 在 myEventHanlder 内部有一个锁,因此预期的行为是 lock 部分内的代码在任何时候都不会执行多次。
但是,在运行应用程序时,有时会遇到锁定代码“并行”执行两次的情况。例如,我可能会看到如下打印输出:
First=0
First=1
Second=0
Second=1
这种情况尤其发生在突发网络事件在很短的持续时间 (
我的问题/要求是:
是什么导致 lock 语句出现这种错误行为。允许锁定代码的 2 个实例?
如何改进代码以提供所需的锁定行为。
谢谢,
-摩西。
【问题讨论】:
-
它正在锁定变量
theLock,但我没有看到分配给它的任何值,你不希望它锁定lockObj吗? -
是否还有其他代码要写入计数器?
-
探矿者上面所说的,您的示例代码使用“theLock”,但暗示它应该使用“lockObj”。也许清理一下你的例子?除此之外,“// do other staff”是否会在事件处理程序完成之前调用任何会导致另一个回调的东西?
-
那是一个错字...编辑了代码。谢谢
-
没有其他代码写入计数器。仅显示增量。 “做员工”部分是纯粹的计算。它不会调用任何会导致另一个回调的东西。
标签: c# multithreading