两个线程调用相同方法时对线程同步的困惑

时间:2012-04-08 22:43:52

标签: c# asynchronous synchronization blocking messenger

我已经创建了一个Messenger库,并且我已经将它设置为线程安全,因此可以在线程之间共享它而不用担心。我主要使用Monitor类来实现这一点。

我有一个Logout例程可能需要一些时间来完成,因为它试图在关闭套接字等之前等待事务发生。它是异步的并且有Begin / End方法,但是对于这个例子我们只是假装它是同步的。

如果两个线程一个接一个地调用Logout会怎样?我应该怎么做第二个线程?

目前我阻止(使用Monitor.Wait从第一个线程等待Pulse),直到第一次注销完成,然后抛出AlreadyLoggedOutException。

如果调用了Logout但是已经发生注销,我还玩弄了一个LogoutInProgress异常。

两者似乎都有优点和缺点,但我想知道其他人认为最好的。

2 个答案:

答案 0 :(得分:2)

您提到的两个中最好的选择是什么,取决于您希望库的行为方式。

我不会将异常抛给使用者,只是在实际注销完成时为两个线程触发结束注销异步事件/方法。您应该使用哪个同步原语来实现这一点取决于您的方法/库的设计。也许如果你分享你提到的Begin End方法的更多细节,我将能够提出更好的建议。

此选项更容易编程。

答案 1 :(得分:0)

有第三个选项:尝试注销的第二个线程可以检测到注销已经发生并且什么都不做。如果“Logout”的合同是“要么确保用户退出,要么退出”,那么你的确应该使Logout成为幂等的。

但是,如果您无法容忍多次注销,因为这将是一个逻辑错误,您应该抛出异常。