代码改变世界

.NET Remoting Basic(4)-客户端调用方式

2010-08-26 22:47  Clingingboy  阅读(427)  评论(0编辑  收藏  举报

分同步,异步和单向方法(即无返回值方法)

1.Servcie端测试代码

class MyRemoteObject: MarshalByRefObject, IMyRemoteObject
 {
     int myvalue;
 
     public MyRemoteObject() 
     {
         Console.WriteLine("MyRemoteObject.Constructor: New Object created");
     }
 
     public void SetValue(int newval)
     {
         Console.WriteLine("MyRemoteObject.setValue(): old {0} new {1}",myvalue,newval);
 
         // we simulate a long running action 
         Console.WriteLine("     .setValue() -> waiting 5 sec before setting value");
         Thread.Sleep(5000);
 
         myvalue = newval;
         Console.WriteLine("     .setValue() -> value is now set");
     }
 
     public int GetValue()
     {
         Console.WriteLine("MyRemoteObject.getValue(): current {0}",myvalue);
         return myvalue;
     }
 
     public string GetName() 
     {
         Console.WriteLine("MyRemoteObject.getName(): called");
 
         // we simulate a long running action 
         Console.WriteLine("     .getName() -> waiting 5 sec before continuing");
         Thread.Sleep(5000);
 
         Console.WriteLine("     .getName() -> returning name");
         return "John Doe";
     }
 }
 
 class ServerStartup
 {
     static void Main(string[] args)
     {
         Console.WriteLine ("ServerStartup.Main(): Server started");
 
         HttpChannel chnl = new HttpChannel(1234);
         ChannelServices.RegisterChannel(chnl);
 
         RemotingConfiguration.RegisterWellKnownServiceType(
                 typeof(MyRemoteObject),
                 "MyRemoteObject.soap", 
                 WellKnownObjectMode.Singleton);
 
         // the server will keep running until keypress.
         Console.ReadLine();
     }
 }


2.同步访问

即一般的访问方法

static void Main(string[] args)
         {
             DateTime start = System.DateTime.Now;
 
             HttpChannel channel = new HttpChannel();
             ChannelServices.RegisterChannel(channel);
             IMyRemoteObject obj = (IMyRemoteObject) Activator.GetObject(
                 typeof(IMyRemoteObject),
                 "http://localhost:1234/MyRemoteObject.soap");
             Console.WriteLine("Client.Main(): Reference to rem.obj. acquired");
 
             Console.WriteLine("Client.Main(): Will set value to 42");
 
             try
             {
                 obj.SetValue(42);
                 Console.WriteLine("Client.Main(): Value successfully set.");
             }
             catch (Exception e)
             {
                 Console.WriteLine("Client.Main(): EXCEPTION.\n{0}", e.Message);
             }
 
             Console.WriteLine("Client.Main(): Will now read value");
             int tmp = obj.GetValue();
             Console.WriteLine("Client.Main(): New server side value {0}", tmp);
 
 
             Console.WriteLine("Client.Main(): Will call getName()");
             String name = obj.GetName();
             Console.WriteLine("Client.Main(): received name {0}",name);
 
             DateTime end = System.DateTime.Now;
             TimeSpan duration = end.Subtract(start);
             Console.WriteLine("Client.Main(): Execution took {0} seconds.",
                                duration.Seconds);
 
             Console.ReadLine();
         }    


测试结果,共花了11秒的时间

image_2

3.异步访问

采用委托的BeginInvoke方法和EndInvoke方法

class Client
 {
     delegate void SetValueDelegate(int value);
     delegate String GetNameDelegate();
 
     static void Main(string[] args)
     {
         DateTime start = System.DateTime.Now;
 
         HttpChannel channel = new HttpChannel();
         ChannelServices.RegisterChannel(channel);
         IMyRemoteObject obj = (IMyRemoteObject) Activator.GetObject(
             typeof(IMyRemoteObject),
             "http://localhost:1234/MyRemoteObject.soap");
         Console.WriteLine("Client.Main(): Reference to rem.obj. acquired");
 
 
         Console.WriteLine("Client.Main(): Will call setValue(42)");
         SetValueDelegate svDelegate = new SetValueDelegate(obj.SetValue);
         IAsyncResult svAsyncres = svDelegate.BeginInvoke(42,null,null);
         Console.WriteLine("Client.Main(): Invocation done");
 
         Console.WriteLine("Client.Main(): Will call getName()");
         GetNameDelegate gnDelegate = new GetNameDelegate(obj.GetName);
         IAsyncResult gnAsyncres = gnDelegate.BeginInvoke(null,null);
         Console.WriteLine("Client.Main(): Invocation done");
 
         Console.WriteLine("Client.Main(): EndInvoke for setValue()");
         svDelegate.EndInvoke(svAsyncres);
         Console.WriteLine("Client.Main(): EndInvoke for getName()");
         String name = gnDelegate.EndInvoke(gnAsyncres);
 
         Console.WriteLine("Client.Main(): received name {0}",name);
 
         Console.WriteLine("Client.Main(): Will now read value");
         int tmp = obj.GetValue();
         Console.WriteLine("Client.Main(): New server side value {0}", tmp);
 
         DateTime end = System.DateTime.Now;
         TimeSpan duration = end.Subtract(start);
         Console.WriteLine("Client.Main(): Execution took {0} seconds.",
                            duration.Seconds);
 
         Console.ReadLine();
     }    
 }


测试结果
虽然增加了复杂度,但提高了程序相应速度

image_4

4.单向访问

当方法无返回值时,可用OneWayAttribute来标记,调用方法相同,同时支持同步与异步操作.

public interface IMyRemoteObject
 {
 
     // no more oneway attribute [OneWay()]
     [OneWay()]
     void SetValue(int newval);
     int GetValue();
     String GetName();
 }