C#:从锁定块调用事件

dew*_*ald 3 c# events multithreading deadlock locking

我经常听说在调用事件监听器之前解锁所有锁是个好主意,以避免死锁.但是,由于lock {}块可以通过C#中的同一个线程重入,是否可以从锁定块调用事件,或者是否需要复制相关的状态数据并在锁定块外部调用事件?

如果没有,请举例说明从lock {}块内调用事件何时出现问题.

谢谢

Mat*_*vis 9

我不记得曾经有必要在lock声明中提出一个事件.但不难想象事情会发生严重变化.

当您举起活动时,您将执行推迟到可能不是您自己的代码.如果您正在编写某些库或框架(例如,将由其他人使用),则尤其如此.在事件处理程序内部,您完全无法控制发生的情况.事件处理程序可以启动一个全新的线程并等待该线程Join()在返回之前完成(即).如果那个新线程调用了一个与你的lock宾果游戏锁定在同一个变量上的函数.僵局.

但除此之外,最佳做法是尽量减少花在内部的时间lock,以减少锁定的"阻塞点"方面.如果你在里面举起一个赛事lock,所有的赌注都会被取消.


Don*_*kby 5

问题不在于事件处理程序可能试图调用您已经拥有的锁,问题在于事件处理程序可能试图获取其他一些锁(可能阻塞并设置了死锁),或者事件处理程序可能会启动一些长期运行的任务,例如数据库查询(直到其他线程完成操作之前,其他线程才能访问您的锁)。一般规则是,您应尽可能短地持有锁。

将线程与您无法控制的事件处理程序混合使用肯定会给您带来麻烦。我目前遇到了一些麻烦,因为我从串行端口的接收线程引发了一个事件。一些事件处理程序代码决定阻止并等待,直到从串行端口接收到另一条消息为止。这将是一个漫长的等待,因为您只是阻塞了一个线程并且仅接收线程!我什至不生气,因为我写了两段代码(相隔一年,所以我有时间忘记细节)。