Multi-thread question with Singleton

A

AMercer

Sorry this is so long winded, but here goes. Following the model of

http://msdn2.microsoft.com/en-us/library/system.runtime.remoting.channels.ipc.ipcchannel.aspx
I made a remote object using the IpcChannel Class (vs 2005, vb, fw 2.0).
Everyting works fine. The object is registered with
WellKnownObjectMode.Singleton
The remote object appears at the bottom of this posting. The code is
deliberately obtuse to expose an issue about when and how single and multiple
threading happen. With a 2 second delay via threading.sleep (blocking) or a
coded while loop (non-blocking), and with clients calling OneUp in rapid
succession, the behavior I see is as follows:

1. With the 2 second delay via while loop (ie threading.sleep is commented
out), multiple client calls to OneUp stack up, and every 2 seconds a call is
completed. In other words, it looks like .net/windows single threads the
calls to OneUp. There is no reentrancy.

2. With the 2 second delay via threading.sleep (ie while loop is commented
out), ONE client application behaves like #1 above.

3. With the 2 second delay via threading.sleep (ie while loop is commented
out), MULTIPLE client applications get tangled up. While the sleep of the
first call to OneUp is running, the second call is allowed to happen, and
thus the functionality of OneUp fails. If the two clients invoke OneUp at
least 2 seconds apart, all is well. If they run in rapid succession, they
both return the same value, ie they run multi-threaded because OneUp is
re-entered. To make things work right, I would have to apply some form of
thread coordination, eg Interlocked.Increment would suffice in this case.

So, when the singleton remote object does a Sleep, its behavior is different
than if it does not do a Sleep. Or am I fooling myself in this observation?
The Sleep is one kind of thread blocking - will the behavior change if a
different kind of blocking happens? How about a WebRequest? How can I
guarantee that a sub in a class does not block? Or maybe throws an exception
if it does block?

The reason for these questions is as follows. I would like to avoid coding
multithread coordination in all the methods that will ultimately be in the
singleton remote object. I know how to do it if I have to, but I don't want
to. What I want my singleton remote object to do is be single threaded and
non-reentrant. If one client is using a remote function, I want others to
block. Can it be done?

The remote object is as follows:

Public Class SingletonRemoteObject
Inherits MarshalByRefObject

Private iOneUp As Integer

Public Function OneUp() As Integer
Dim k As Integer = iOneUp + 1
Dim dt As DateTime = Now.AddSeconds(2)

'While Now < dt : End While ' non-blocking 2 second delay
System.Threading.Thread.Sleep(2000) ' blocking 2 second delay

iOneUp = k
Return k
End Function

End Class
 
J

Jon Skeet [C# MVP]

AMercer said:
Sorry this is so long winded, but here goes. Following the model of

http://msdn2.microsoft.com/en-us/library/system.runtime.remoting.channels.ipc.ipcchannel.aspx
I made a remote object using the IpcChannel Class (vs 2005, vb, fw 2.0).
Everyting works fine. The object is registered with
WellKnownObjectMode.Singleton
The remote object appears at the bottom of this posting. The code is
deliberately obtuse to expose an issue about when and how single and multiple
threading happen. With a 2 second delay via threading.sleep (blocking) or a
coded while loop (non-blocking), and with clients calling OneUp in rapid
succession, the behavior I see is as follows:

1. With the 2 second delay via while loop (ie threading.sleep is commented
out), multiple client calls to OneUp stack up, and every 2 seconds a call is
completed. In other words, it looks like .net/windows single threads the
calls to OneUp. There is no reentrancy.

Well, at that point you've got a tight loop - so it's not like you're
playing nicely and letting other threads have much of a look-in.
2. With the 2 second delay via threading.sleep (ie while loop is commented
out), ONE client application behaves like #1 above.

3. With the 2 second delay via threading.sleep (ie while loop is commented
out), MULTIPLE client applications get tangled up. While the sleep of the
first call to OneUp is running, the second call is allowed to happen, and
thus the functionality of OneUp fails. If the two clients invoke OneUp at
least 2 seconds apart, all is well. If they run in rapid succession, they
both return the same value, ie they run multi-threaded because OneUp is
re-entered. To make things work right, I would have to apply some form of
thread coordination, eg Interlocked.Increment would suffice in this case.

Indeed. That's almost certainly the way to go.
So, when the singleton remote object does a Sleep, its behavior is different
than if it does not do a Sleep. Or am I fooling myself in this observation?
The Sleep is one kind of thread blocking - will the behavior change if a
different kind of blocking happens? How about a WebRequest? How can I
guarantee that a sub in a class does not block? Or maybe throws an exception
if it does block?

I suspect you'd find that in *some* cases your tight loop would act in
exactly the same way - particularly on multi-processor boxes.

Both of your ways of pausing are blocking, by the way - they're
blocking the current thread from doing any more work until they've
finished the "pause".
The reason for these questions is as follows. I would like to avoid coding
multithread coordination in all the methods that will ultimately be in the
singleton remote object. I know how to do it if I have to, but I don't want
to. What I want my singleton remote object to do is be single threaded and
non-reentrant. If one client is using a remote function, I want others to
block. Can it be done?

Use a shared lock which you take out for the whole of every remote
call. It's fairly easy to do, although it won't scale at all, of
course.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top