Question

I've created a Messenger library and I've made it thread safe so it can be shared around between threads without worry. I achieve this mostly using the Monitor class.

I have a Logout routine which can take some time to complete because it tries to wait for transactions taking place before it shuts down the socket etc. It's asynchronous and has Begin/End methods, but for this example we'll just pretend it's synchronous.

What if two threads call Logout, one right after another? What should I be doing with the second thread?

Currently I block (using Monitor.Wait to wait for a Pulse from the first thread) until the first logout completes and then throw a AlreadyLoggedOutException.

I've also toyed with having a LogoutInProgress exception thrown if Logout is called but a logout is already taking place.

Both seem to have advantages and disadvantages, but I'd like to know what other people think is best.

Was it helpful?

Solution

What is the best option out of the two you mentioned, depends on how you want your library to behave.

I would not throw the exception to the consumer and simply fire the end logout async event/method for both of the threads when the actual logout completes. Which synchronization primitive you should be using to achieve this depends on the design of your method/library. Maybe if you share more details on the Begin End method you mentioned, i'll be able to suggest better.

This option would be easier to program against.

OTHER TIPS

There is a 3rd option: The second thread trying to Logout could detect, that a logout already happened and do nothing. If the contract of "Logout" is "either ensure that the user is logged out, or throw" then you should indeed make Logout idempotent.

However if you cannot tolerate multiple logouts because that would be a logic error somehow you should throw an exception.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top