Hi,

I have the example. It is not perfect as an example, but i didn't have much
time to do it.
Succinctly, if you have an array with a MarshalByRefObject descendant, each
one with a client manage by a different thread, remoting will be blocked if
the servers call other servers all managed by different threads. This will
not always happen, but if you increase the number of severs calling other
servers after some number of threads this will happen almost for sure.
In the example you can increase the constant UNITS and verify that after
some value remoting communications will be blocked.
To test the application, press button1 to start the threads responsible for
the calls and then press button2 in order to verify if remoting is blocked.

Regards,

Manuel






using System;

using System.Drawing;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

using System.Data;

using System.Runtime.Remoting;

using System.Runtime.Remoting.Channels;

using System.Runtime.Remoting.Channels.Tcp;

using System.Runtime.Remoting.Channels.Http;

using System.Threading;

namespace RemotingTest

{


#region Synchronizer component

public class SynchronizerComp : MarshalByRefObject

{

private int count = 1;

public void Wait()

{

lock(this)

{

while(count<=0)

{

Monitor.Wait(this,System.Threading.Timeout.Infinite);

}


count--;

}


}

public void Release()

{

lock(this)

{

count++;

Monitor.Pulse(this);

}

}

}

#endregion

#region Class to register Test classes in a different application domain

public class ServerCreator : MarshalByRefObject

{

public void RegisterURIsForRemoting(int NumbOfServers)

{

TcpChannel Channel = new TcpChannel(3000);

ChannelServices.RegisterChannel(Channel);



Type type = Type.GetType("RemotingTest.Test,RemotingTest");

//Register URIs for remoting

for(int i = 0; i<NumbOfServers; i++)

RemotingConfiguration.RegisterWellKnownServiceType(type,"Test" +
i.ToString(),WellKnownObjectMode.Singleton);

RemotingConfiguration.RegisterWellKnownServiceType(Type.GetType("RemotingTes
t.SynchronizerComp,RemotingTest"),"Mutex",WellKnownObjectMode.Singleton);

}

}

#endregion


delegate void AsynchronousIncNeighbor();


public class Test : MarshalByRefObject

{

private long count = 0;

private SynchronizerComp mutex;

private Test[] neighbor = new Test[1024];

private AsynchronousIncNeighbor[] asynchronousIncNeighbor = new
AsynchronousIncNeighbor[1024];

private long countNeighbors = 0;

public void SetMutex(SynchronizerComp synchronizerComp)

{

mutex = synchronizerComp;

}

public void Increment(){

//All the instances of the Test class will increment their count one at a
time


if(mutex!=null)

mutex.Wait();


count++;


if(mutex!=null)

mutex.Release();

}

public long Count{get{return count;}}

public long CountNeighbors{get{return countNeighbors;}}

public Test Neighbor(int NeighborIndex){return neighbor[NeighborIndex];}

public void AddNeighbor(Test Neighbor)

{

neighbor[countNeighbors] = Neighbor;

asynchronousIncNeighbor[countNeighbors] = new
AsynchronousIncNeighbor(neighbor[countNeighbors].Increment);

countNeighbors++;

}

public void IncrementAllNeighbors()

{

for(int i = 0; i<countNeighbors; i++)

asynchronousIncNeighbor[i].BeginInvoke(null,null);

}

public string HelloWorld

{

get{return "Hi there, remoting is working";}

}

}

/// <summary>

/// Summary description for Form1.

/// </summary>

public class Form1 : System.Windows.Forms.Form

{

private System.Windows.Forms.Button button1;

private System.Windows.Forms.Button button2;

/// <summary>

/// Required designer variable.

/// </summary>

private System.ComponentModel.Container components = null;


//##########################################################################
#################

//##########################################################################
#################

//##########################################################################
#################


private const int UNITS = 2; //In my machine with 3 or more, remoting
communications will be blocked

//##########################################################################
#################



//##########################################################################
#################

//##########################################################################
#################



private Test[] test = new Test[UNITS];

private Thread[] threadList = new Thread[UNITS];

private AppDomain domain = null;

private SynchronizerComp mutex = null;


public Form1()

{

//

// Required for Windows Form Designer support

//

InitializeComponent();

//

// TODO: Add any constructor code after InitializeComponent call

//

}

/// <summary>

/// Clean up any resources being used.

/// </summary>

protected override void Dispose( bool disposing )

{

if( disposing )

{

if (components != null)

{

components.Dispose();

}

}

base.Dispose( disposing );

}

#region Windows Form Designer generated code

/// <summary>

/// Required method for Designer support - do not modify

/// the contents of this method with the code editor.

/// </summary>

private void InitializeComponent()

{

this.button1 = new System.Windows.Forms.Button();

this.button2 = new System.Windows.Forms.Button();

this.SuspendLayout();

//

// button1

//

this.button1.Location = new System.Drawing.Point(16, 16);

this.button1.Name = "button1";

this.button1.Size = new System.Drawing.Size(144, 40);

this.button1.TabIndex = 0;

this.button1.Text = "Increment Neighbors";

this.button1.Click += new System.EventHandler(this.button1_Click);

//

// button2

//

this.button2.Location = new System.Drawing.Point(16, 64);

this.button2.Name = "button2";

this.button2.Size = new System.Drawing.Size(144, 40);

this.button2.TabIndex = 1;

this.button2.Text = "Test if remoting is working";

this.button2.Click += new System.EventHandler(this.button2_Click);

//

// Form1

//

this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);

this.ClientSize = new System.Drawing.Size(176, 117);

this.Controls.AddRange(new System.Windows.Forms.Control[] {

this.button2,

this.button1});

this.Name = "Form1";

this.Text = "Form1";

this.Load += new System.EventHandler(this.Form1_Load);

this.ResumeLayout(false);

}

#endregion

/// <summary>

/// The main entry point for the application.

/// </summary>

[STAThread]

static void Main()

{

Application.Run(new Form1());

}

private int threadIndex;

private void IncrementNeighbors()

{

Test t;

lock(this)

{

t = test[threadIndex];

threadIndex++;

}



for(int i = 0; i<10; i++)

t.IncrementAllNeighbors();

}


private void DoCalls()

{

//Start incrementing neighbors

for(int i = 0; i<test.Length; i++)

{

threadList[i] = new Thread(new ThreadStart(IncrementNeighbors));

threadList[i].IsBackground = true;

threadList[i].Start();

}

}

private void MultithreadCallAndWait()

{

threadIndex = 0;

DoCalls();


//Wait for the end of all threads

for(int i = 0; i<test.Length; i++)

{

threadList[i].Join();

}

}


private void button1_Click(object sender, System.EventArgs e)

{

//Activate the process by pressing this button


//Add neighbors

if(test[0].CountNeighbors==0)

for(int i = 0; i<test.Length; i++)

{

for(int ii = 0; ii<test.Length; ii++)

if(i!=ii)

test[i].AddNeighbor(test[ii]);

}


//Start increment neighbors

Thread t = new Thread(new ThreadStart(MultithreadCallAndWait));

t.IsBackground = true;

t.Start();


}

private void button2_Click(object sender, System.EventArgs e)

{

//After pressing button 1, try to press this one

//try to access one of the servers

MessageBox.Show(test[0].HelloWorld);

}



private void Form1_Load(object sender, System.EventArgs e)

{


//Create a new domain to host Test instances

domain = AppDomain.CreateDomain("Remoting Test");

ServerCreator creator =
(ServerCreator)domain.CreateInstanceAndUnwrap("RemotingTest","RemotingTest.S
erverCreator");


//Register Test URIs

creator.RegisterURIsForRemoting(test.Length);

int cNumber = 3000;

//Get a proxy to the "mutex"

mutex =
(SynchronizerComp)Activator.GetObject(typeof(RemotingTest.SynchronizerComp),
"tcp://localhost:" + cNumber + "/mutex");

//Create proxies

for(int i = 0; i<test.Length; i++)

{

test[i] =
(Test)Activator.GetObject(typeof(RemotingTest.Test),"tcp://localhost:" +
cNumber + "/Test" + i.ToString());

test[i].SetMutex(mutex);

}

}



}

}

You can read messages from the Advanced DOTNET archive, unsubscribe from Advanced 
DOTNET, or
subscribe to other DevelopMentor lists at http://discuss.develop.com.

Reply via email to