Topaz Filer - Email filing software
Synchronization in .Net Remoting
Messages   Related Types
This message was discovered on microsoft.public.dotnet.distributed_apps.
Responses highlighted in red are from those people who are likely to be able to contribute good, authoratitive information to this discussion. They include Microsoft employees, MVP's and others who IMHO contribute well to these kinds of discussions.

Chun Fan (VIP)
hi, there,

I am recently using .net remoting to develop a distributed application and
some synchronization problem bothered for a long time.

The problem looks as following:
There is one server application that hosts a remote object, "mydata". This
remote object is configured as a singlton object. Three functions are
developed within this object to provide synchronized data access:
public class MyData :MarshalByRefObject{

....
public void Lock(){
System.Threading.Monitor.Enter(this);
}

public void Release(){
System.Threading.Monitor.Exit(this);
}

public bool TryLock(){
return System.Threading.Monitor.TryEnter(this);
}
....
}

And two client applications with similar behavior that at first, each client
application tries to obtain the lock on mydata by invoking mydata.Lock();
then does some processing. After the processing is done, the client will
display a message box by invoking 'MessageBox.show()' and waiting for user's
input. After the user's input is received, the client will invoke
mydata.Release() to release the lock on mydata such that other clients may be
able to access mydata.

So I started the first client. The client obtained the lock and displayed
the message box, waiting for my input. Then the second client was started. If
everything were working, the second client should have been blocked since it
can not obtain the lock. Unfortunately, the second client just went on as if
it had got the lock and also displays the message box!

The more wierd thing was that after a random length of time(several minutes
to hours), the lock could work!, i.e. before one client releases the lock,
the other one is blocked at the mydata.Lock() invocation!

So could anybody help me to tell me what's wrong here? Or anybody can tell
me how to implment such a locking in the .net remoting? Thanks a lot!
--
Sincerely

Chun
Reply to this message...
Vote that this is a GOOD answer...
 
 
    
Chun Fan (VIP)
More information I got:
If I do nothing after starts the client, i.e. not trying to access the
remote object, for several minutes, the blocking mechanism works smoothly.
Anyone can give me a hand to let me know what's wrong here? Is that my
program error or a bug of .net framework? Thanks a lot!

"Chun Fan" wrote:

[Original message clipped]

Reply to this message...
Vote that this is a GOOD answer...
 
 
    
Sam Santiago
What are you doing within your Singleton object that you need
synchronization? I do not think it's a good idea to have your clients
control the synchronization, especially via a remote method call. This
pushes the responsibility of synchronization management to the client which
assumes all your clients will be coded properly. A single badly coded
client could cause your entire server object to become unusable by any other
clients - too big a risk.

I recommend having the synchronization management done strictly server side.
Your clients should simply acquire a reference to your Singleton an execute
the needed method. Your Singlton should on the server side within the
methods that need synchronization use a Monitor to synchronize the
appropriate activity.

Lastly, if you want a true Singleton be sure to override the
InitializeLifetimeService method provided from the MarshalByRefObject to
return null. Some of the behavior you're observing might be due to the fact
that your object's lifetime lease has expired (5 min default from the last
method call) and a new object is created when you invoke your SAO after a
few minutes.

Thanks,

Sam

--
_______________________________
Sam Santiago
Click here to reveal e-mail address
http://www.SoftiTechture.com
_______________________________
"Chun Fan" <Click here to reveal e-mail address> wrote in message
news:Click here to reveal e-mail address...
[Original message clipped]

Reply to this message...
Vote that this is a GOOD answer...
 
 
    
Chun Fan (VIP)
Thanks for your answer. If the client doesn't need to acquire several
different locks on different remote objects before performing any real
processing work, it is a good idea to control the syncrhonization strictly on
the server side. Actually, I am implementing a two-phase locking like
application. So at the first phase, the client should acquire all the locks
(which may on different remote objects), then the client can perform some
processing at its side, after that, the client should release all the locks
have been acquired. The locks may on different server/remote objects so it is
necessary for the client to control the lock. However, the actual locks are
on the server side.

Secondly, the InitializeLifetimeService method has been overrided to return
null and that didn't solve the problem.

And now the problem is that if I do NOTHING after the clients start, after 2
~ 5 minutes, the blocking mechanism works smoothly. However, if I let the
clients access the remote objects from the beginning, the blocking doesn't
work. And if I stop allowing the clients to access the remote objects for a
while, the blocking can work again. So any suggestions to solve this? Thanks
a lot!
"Sam Santiago" wrote:

[Original message clipped]

Reply to this message...
Vote that this is a GOOD answer...
 
 
    
Sam Santiago
If you can post some code that would probably make things more clear. Have
you considered how you would handle deadlocks? If you need distributed
transactions you might consider EnterpriseServices vs. trying to implement
your own locking mechanism.

Thanks,

Sam

--
_______________________________
Sam Santiago
Click here to reveal e-mail address
http://www.SoftiTechture.com
_______________________________
"Chun Fan" <Click here to reveal e-mail address> wrote in message
news:Click here to reveal e-mail address...
[Original message clipped]

Reply to this message...
Vote that this is a GOOD answer...
 
Double-click to open VS solution with elevated permissions on Windows 7
New BootFX DBGet build available
 
    
Chun Fan (VIP)
Actually, the related server side object code has been posted. The following
is the related client side code:

public class Client {
....
mydata = new MyData(); // MyData is a remote singleton object on the
server
....
mydata.Lock();
... // acquire other locks and do some processing
mydata.Release();
....
}

What we are trying to do is to demonstrate the two-phase locking and
two-phase committment using .Net. I am not familiar with .net's enterprise
services so I do not know if it allows me to do things like this: acquire all
the locks before doing processing and then release all the locks. Any
suggestions? thanks a lot!

"Sam Santiago" wrote:

[Original message clipped]

Reply to this message...
Vote that this is a GOOD answer...
 
 
    
Sam Santiago
You might want to read this article:

HOW TO: Perform a Distributed Transaction with a .NET Provider by Using
ServicedComponent in Visual Basic .NET
http://support.microsoft.com/default.aspx?scid=kb;en-us;316627

You might want to read up on Enterpise Services:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/entserv.asp

Thanks,

Sam

--
_______________________________
Sam Santiago
Click here to reveal e-mail address
http://www.SoftiTechture.com
_______________________________
"Chun Fan" <Click here to reveal e-mail address> wrote in message
news:Click here to reveal e-mail address...
> Actually, the related server side object code has been posted. The
following
[Original message clipped]

Reply to this message...
Vote that this is a GOOD answer...
 
Twitter and Snow… simple #uksnow
Windows 7 compatible tool for mounting ISO images
 
    
Chun Fan (VIP)
Let me take a look. Thanks a lot!

"Sam Santiago" wrote:

[Original message clipped]

Reply to this message...
Vote that this is a GOOD answer...
 
 
    
Chun Fan (VIP)
The articles are good. but I am now wondering why the simplest, the most
straight forward way can not work as expected. As I have said, only if I do
not use the clients to access the remote object, everything works just find
and smoothly. So how come they work like this? Thanks!

"Sam Santiago" wrote:

[Original message clipped]

Reply to this message...
Vote that this is a GOOD answer...
 
 
    
Sam Santiago
Without posting detailed code snippets showing how you configure remoting
and your server and client objects it's difficult to say. I think the main
point is that there are many other complicating issues to think about that
Enterprise Services addresses.

Thanks,

Sam

--
_______________________________
Sam Santiago
Click here to reveal e-mail address
http://www.SoftiTechture.com
_______________________________
"Chun Fan" <Click here to reveal e-mail address> wrote in message
news:Click here to reveal e-mail address...
[Original message clipped]

Reply to this message...
Vote that this is a GOOD answer...
 
Introduction to BootFX’s Object Relational Mapping Functionality article now live on CodeProject
Xenu Link Sleuth
 
    
Chun Fan (VIP)
/// remote object code
[Serializable]
    public class Data_2:MarshalByRefObject
    {
        public Data_2()
        {
            m_nID = 2;
            m_nOwnerActorID = 1;
            m_strName = "Data 2";
            dataValueString = "";
            dataType = "";
            obj = new object();
            mutex = new System.Threading.Mutex(true);
        }

        public bool TryLock()
        {
//            return mutex.WaitOne(100, true);
            
            return System.Threading.Monitor.TryEnter(this);
        }

        public void Lock()
        {
//            mutex.WaitOne();
            System.Threading.Monitor.Enter(this);
        }

        public void Release()
        {
//            mutex.ReleaseMutex();

            System.Threading.Monitor.Pulse(this);
            System.Threading.Monitor.Exit(this);
        }
    
        public object obj;
        public System.Threading.Mutex mutex;
    }

/// server code
public class RemoteLoader: MarshalByRefObject
    {
        public RemoteLoader()
        {
            m_arrDatas = new ArrayList();
            m_arrAssemblies = new ArrayList();
        }

        
        public void LoadAvailableDatas()
        {
            
            string[] DataFiles =
Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.dll");

            foreach (string filename in DataFiles)
            {
                Assembly a = Assembly.LoadFrom(filename);
                m_arrAssemblies.Add(a);
            }
            RemotingConfiguration.Configure( @"..\..\server.exe.config" );
        }

    

        public int Length
        {
            get {return m_arrDatas.Count;}
        }

        private ArrayList m_arrAssemblies;

        private ArrayList m_arrDatas;
    }

/// server configuration file
<configuration>
    <system.runtime.remoting>
        <application name="Server">
            <service>
                <wellknown mode="Singleton" type="ConcreteData.Data_2, ConcreteACDATE"
objectUri="Data_2_URI" />
            <channels>
                <channel ref="http" port="8080" />
                <channel ref="tcp" port="8081" />
            </channels>
        </application>
    </system.runtime.remoting>
</configuration>

/// client code
/// have been shown in previous posts:)

/// client configuration
<configuration>
    <system.runtime.remoting>
        <application name="Client">
            <client>
                <wellknown type="ConcreteACDATE.Data_2, ConcreteACDATE"
url="tcp://localhost:8081/Data_2_URI" />
            </client>
            <channels>
                
                <channel ref="tcp" port="0">
                    <clientProviders>
                        <formatter ref="binary" />
                    </clientProviders>
                    <serverProviders>
                        <formatter ref="binary" typeFilterLevel="Full" />
                    </serverProviders>
                </channel>
                
            </channels>
        </application>
    </system.runtime.remoting>
</configuration>

Is that detailed enough? Thanks a lot!

Chun

"Sam Santiago" wrote:

[Original message clipped]

Reply to this message...
Vote that this is a GOOD answer...
 
 
    
Sam Santiago
I don't know what's going on, but I don't believe the Monitor object will
help you create a distributed application object lock. Monitor will allow 1
thread to lock an object, preventing other threads from accessing it. But
you are not in control of the threads that access your remote object - it's
all handled by the remoting infrastructure. In fact, there is no guarantee
that the same thread services all requests for the same client. You would
have to write a application level locking mechanism that would "lock" your
remote object and keep track of which client owns that lock. You would have
to synchronize within your methods that acquire and release your application
lock, so Monitor could help there. Good luck.

Thanks,

Sam

--
_______________________________
Sam Santiago
Click here to reveal e-mail address
http://www.SoftiTechture.com
_______________________________
"Chun Fan" <Click here to reveal e-mail address> wrote in message
news:Click here to reveal e-mail address...
[Original message clipped]

Reply to this message...
Vote that this is a GOOD answer...
 
 
    
Chun Fan (VIP)
GOOD ANSWER
got it. thanks:)

"Sam Santiago" wrote:

[Original message clipped]

Reply to this message...
Vote that this is a GOOD answer... (1 vote from another user already)
 
 
    
Chun Fan (VIP)
For one more thing, I am using VS.net 2003 pro and Windows XP running one a
P4 desktop. Thanks!

"Chun Fan" wrote:

[Original message clipped]

Reply to this message...
Vote that this is a GOOD answer...
 
 
 
System.AppDomain
System.Collections.ArrayList
System.EnterpriseServices.ServicedComponent
System.IO.Directory
System.MarshalByRefObject
System.Reflection.Assembly
System.Runtime.Remoting.RemotingConfiguration
System.Threading.Monitor
System.Threading.Mutex
System.Windows.Forms.MessageBox




Topaz Filer - Email filing software
Ad
BootFX
Reliable and powerful .NET application framework.
Looking to invest in a major software project? Technical and commercial advice available here.
Other Helpful Sites
MBR 247
Topaz Filer
SharePoint Email Filing
Software Advisory Services
 
Copyright © AMX Software Ltd 2008-2010. Portions copyright © Matthew Baxter-Reynolds 2001-2010. All rights reserved.
Contact Us - Terms of Use - Privacy Policy - 4.0.30129.1734