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
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