Click here to Skip to main content
15,895,192 members
Articles / Programming Languages / C#

Using the Remoting Callbacks in .Net Applications.

Rate me:
Please Sign up or sign in to vote.
3.45/5 (18 votes)
1 Dec 200111 min read 235.3K   2.9K   128  
This article describes how to implement an asynchronous remoting callbacks from different remote objects such as .Net Service (COM+), Web Service and classic .Net object using the C# language.
//--------------------------------------------
// Written by Roman Kiss (rkiss@pathcom.com)
// November 14, 2001
// 
// history:
// RK	10142001	init
//--------------------------------------------

using System;
using System.Diagnostics;
using System.Threading;
using System.Drawing;
using System.Collections;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Configuration;
//
using System.Runtime.Remoting;
using System.Runtime.Remoting.Activation;
using System.Runtime.Remoting.Lifetime;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels.Http;
using System.Reflection;
using System.Runtime.InteropServices;
//
using RKiss.RemoteObject;			// abstract definitions
using RKiss.RemoteCallbackLib;		// custom attribute, subscriber



namespace RKiss.RemoteWindowsForm
{
	// delegate for asynch invoking
	public delegate string DelegateGiveMeCallback(int timeinsec, string ticketId, object objwire);

	// -----------< Callback class >-------------------------------------------
	public class CallbackClass : MarshalByRefObject
	{	
		private Form1 _parent = null;
		private bool  _state = false;
		public Form1 Parent	{ set { _parent = value; }}
		public bool State   { set { lock(this) { _state = value; }}}
		// set a leaseing time for infinity
		public override Object InitializeLifetimeService()
		{
			ILease lease = (ILease)base.InitializeLifetimeService();
			if(lease.CurrentState == LeaseState.Initial)  
			{
				lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
			}
			return lease;
		}
		//
		// CallbackMethod
		public bool Progress(string sender, object e) 
		{
			// fire&forget
			ThreadPool.QueueUserWorkItem(new WaitCallback(DispatchEvent), e);
			return _state;
		}
		// helper
		private void DispatchEvent(object e) 
		{
			CallbackEventArgs cea = e as CallbackEventArgs;
			// a simple work with the parent's control
			lock(this) 
			{
				if(cea.TicketId == "ProgressBar") 
				{
					if(cea.State is int)
					{
						_parent.TextBoxStatus.Text = cea.State.ToString();
						_parent.ProgressBarStatus.PerformStep();
					}
					else
					if(cea.State is string)
						_parent.TextBoxStatus.Text = cea.State.ToString();
				}
				else
				if(cea.TicketId == "TextBox") 
				{
					if(_parent.TextBoxStatus.BackColor == Color.Yellow)
						_parent.TextBoxStatus.BackColor = Color.White;
					else
						_parent.TextBoxStatus.BackColor = Color.Yellow;
				}
				else
				if(cea.TicketId == "Button") 
				{
					if(_parent.ButtonRM.ForeColor == Color.Magenta)
						_parent.ButtonRM.ForeColor = Color.Black;
					else
						_parent.ButtonRM.ForeColor = Color.Magenta;
				}
			}
		}
	} // end of the CallbackClass
	


	// Windows Form
	public class Form1 : System.Windows.Forms.Form
	{
		private System.Windows.Forms.Button buttonRM;
		private System.Windows.Forms.TextBox textBoxStatus;
		private System.Windows.Forms.ProgressBar progressBarStatus;

		// --------< remoting and callback >------------------------------------
		[RemoteCallback("tcp", desc="Callbacks Test")]
		public CallbackClass cb = null;
		// Remote ObjectA
		private IRmObject roA = null;
		// Remote ObjectX
		private IRmObject roX = null;
		// Remote ObjectWS
		private IRmObject roWS = null;
		// callback Admin
		private RemoteCallbackSubscriber sub = null;
		// Access to the controls
		public ProgressBar ProgressBarStatus { get { return progressBarStatus; }}
		public TextBox     TextBoxStatus { get { return textBoxStatus; }}
		public Button      ButtonRM { get { return buttonRM; }}
	
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;
		
		public Form1()
		{
			InitializeComponent();

			try 
			{
				sub = new RemoteCallbackSubscriber(this);
				cb.Parent = this;	// we need an access to the parent properties

				// get the remoting uriAddress
				NameValueCollection uriAddr = (NameValueCollection)ConfigurationSettings.GetConfig("Client/urlAddress");
				string uriObjectA = (string)uriAddr["objectA"];
				string uriObjectX = (string)uriAddr["objectX"];
				string uriObjectWS = (string)uriAddr["objectWS"];

				// type of the Remote Interface
				Type typeofRI = typeof(RKiss.RemoteObject.IRmObject);

				// create a proxy of the remote objects
				roA = (IRmObject)Activator.GetObject(typeofRI, uriObjectA);
				roX = (IRmObject)Activator.GetObject(typeofRI, uriObjectX);
				roWS = (IRmObject)Activator.GetObject(typeofRI, uriObjectWS); 
				//
				// (sub["cb"] as TcpChannel).StartListening(0);	// sample how to control a Tcp channel

				// echo test
				textBoxStatus.Text = roWS.Echo(roA.Echo(roX.Echo("This is an ECHO Message")));
			}
			catch(Exception ex)
			{
				textBoxStatus.Text = ex.Message;
				buttonRM.Hide();
			}
		}

		/// <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.textBoxStatus = new System.Windows.Forms.TextBox();
			this.buttonRM = new System.Windows.Forms.Button();
			this.progressBarStatus = new System.Windows.Forms.ProgressBar();
			this.SuspendLayout();
			// 
			// textBoxStatus
			// 
			this.textBoxStatus.Anchor = ((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
				| System.Windows.Forms.AnchorStyles.Right);
			this.textBoxStatus.BackColor = System.Drawing.Color.White;
			this.textBoxStatus.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.textBoxStatus.Location = new System.Drawing.Point(8, 32);
			this.textBoxStatus.Name = "textBoxStatus";
			this.textBoxStatus.ReadOnly = true;
			this.textBoxStatus.Size = new System.Drawing.Size(224, 20);
			this.textBoxStatus.TabIndex = 2;
			this.textBoxStatus.Text = "status";
			// 
			// buttonRM
			// 
			this.buttonRM.Anchor = (System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right);
			this.buttonRM.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.buttonRM.ForeColor = System.Drawing.SystemColors.ControlText;
			this.buttonRM.Location = new System.Drawing.Point(232, 32);
			this.buttonRM.Name = "buttonRM";
			this.buttonRM.Size = new System.Drawing.Size(64, 23);
			this.buttonRM.TabIndex = 1;
			this.buttonRM.Text = "Run";
			this.buttonRM.Click += new System.EventHandler(this.buttonRM_Click);
			// 
			// progressBarStatus
			// 
			this.progressBarStatus.Anchor = ((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
				| System.Windows.Forms.AnchorStyles.Right);
			this.progressBarStatus.Location = new System.Drawing.Point(8, 8);
			this.progressBarStatus.Name = "progressBarStatus";
			this.progressBarStatus.Size = new System.Drawing.Size(288, 16);
			this.progressBarStatus.TabIndex = 0;
			// 
			// Form1
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.ClientSize = new System.Drawing.Size(304, 61);
			this.Controls.AddRange(new System.Windows.Forms.Control[] {
																		  this.textBoxStatus,
																		  this.buttonRM,
																		  this.progressBarStatus});
			this.Name = "Form1";
			this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
			this.Text = "Remote Callback";
			this.TopMost = true;
			this.ResumeLayout(false);

		}
		#endregion

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main() 
		{
			Application.Run(new Form1());
		}
		// run in the objectA, objectX and objectWS simultaneusly
		private void buttonRM_Click(object sender, System.EventArgs e)
		{
			try 
			{
				if(buttonRM.Text == "Run") 
				{
					// client state
					buttonRM.Text = "Busy";
					progressBarStatus.Value = 0;
					textBoxStatus.Text = string.Empty;
					cb.State = true;
					//
					// arguments
					int timeinsec = 10;
					string ticketId = "ProgressBar";
					RemoteCallback wire = new RemoteCallback(cb.Progress);
					//
					// invoking method on the objectA
					AsyncCallback acbA = new AsyncCallback(asyncCallBackA);
					DelegateGiveMeCallback dA = new DelegateGiveMeCallback(roA.GiveMeCallback);
					IAsyncResult arA = dA.BeginInvoke(timeinsec, ticketId, wire, acbA, null);
					//
					// invoking method on the objectX
					AsyncCallback acbX = new AsyncCallback(asyncCallBackX);
					DelegateGiveMeCallback dX = new DelegateGiveMeCallback(roX.GiveMeCallback);
					IAsyncResult arX = dX.BeginInvoke(timeinsec, "TextBox", wire, acbX, null);
					//
					// invoking method on the objectWS
					AsyncCallback acbWS = new AsyncCallback(asyncCallBackWS);
					DelegateGiveMeCallback dWS = new DelegateGiveMeCallback(roWS.GiveMeCallback);
					IAsyncResult arWS = dWS.BeginInvoke(timeinsec, "Button", wire, acbWS, null);
					//
					buttonRM.Text = "Abort";
				}
				else
				if(buttonRM.Text == "Abort")
				{
					cb.State = false;
				}
			}
			catch(Exception ex)
			{
				textBoxStatus.Text = ex.Message;
				buttonRM.Text = "Run";
			}
		}
		// async result from the remoting objects
		private void asyncCallBackA(IAsyncResult ar)
		{
			DelegateGiveMeCallback d = (DelegateGiveMeCallback)((AsyncResult)ar).AsyncDelegate;
			object o = d.EndInvoke(ar);
			buttonRM.Text = "Run";
		}
		private void asyncCallBackX(IAsyncResult ar)
		{
			DelegateGiveMeCallback d = (DelegateGiveMeCallback)((AsyncResult)ar).AsyncDelegate;
			object o = d.EndInvoke(ar);
			buttonRM.Text = "Run";
		}
		private void asyncCallBackWS(IAsyncResult ar)
		{
			DelegateGiveMeCallback d = (DelegateGiveMeCallback)((AsyncResult)ar).AsyncDelegate;
			object o = d.EndInvoke(ar);
			buttonRM.Text = "Run";
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior)
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions