2012-04-08 138 views
0

我創建了一個Messenger庫,並且使線程安全,因此可以在線程之間共享,而不用擔心。我主要使用Monitor類來實現這一點。兩個線程調用同一個方法時線程同步的困惑

我有一個註銷例程,可能需要一些時間才能完成,因爲它試圖在它關閉套接字之前等待發生的事務。它是異步的並具有Begin/End方法,但對於此示例,我們只是假裝它是同步的。

如果兩個線程調用Logout,一個接一個地怎麼辦?我應該如何處理第二個線程?

當前我阻止(使用Monitor.Wait等待來自第一個線程的脈衝),直到第一個註銷完成,然後拋出AlreadyLoggedOutException。

我也玩過一個LogoutInProgress異常,如果註銷被調用但已經發生注入。

兩者似乎都有優點和缺點,但我想知道其他人認爲最好的。

回答

2

你提到的兩個中最好的選擇是什麼,取決於你希望你的圖書館如何表現。

我不會拋出異常給使用者,只是在實際的註銷完成時爲兩個線程啓動結束註銷異步事件/方法。您應該使用哪種同步原語來實現這一點取決於您的方法/庫的設計。也許如果你分享了你提到的Begin Begin方法的更多細節,我將能夠提出更好的建議。

這個選項會比較容易編程。

+0

它的異步方面並不重要。你說什麼Logout方法應該只是返回(無效)他們兩人後註銷發生沒有任何異常? – NoPyGod 2012-04-08 23:04:41

+0

如果他們兩個都打算註銷同一個客戶端,並且操作是冪等的,那麼拋出異常沒有意義。 – 2012-04-08 23:07:52

+0

有例外的邏輯很有意義,謝謝。但是你真的相信,註銷電話應該「阻止」,直到實際註銷完成?理論上,我可以從第二次註銷返回,因爲第一次註銷在某個時刻保證成功。我看到的問題是,它會給調用者一個錯誤的註銷完成時,事實上它仍在發生。 – NoPyGod 2012-04-08 23:25:49

0

還有第三種選擇:嘗試登出的第二個線程可以檢測到註銷已經發生並且什麼都不做。如果「註銷」合同是「確保用戶註銷或丟棄」,那麼您確實應該使註銷成爲冪等。

但是,如果你不能容忍多次註銷,因爲這會是一個邏輯錯誤,你應該拋出一個異常。