.Net 3.5 Remoting编程入门四
.Net 3.5 Remoting编程入门四
自定义远程对象异常
异常要的处理是每个应用程序都应该考虑的问题。在Remoting应用程序中,客户端调用服务器上的远程对象,如果远程对象内部处理时发生了异常或者触发了我们自定义的异常,那么如何将这个异常传递到客户端?下面我们来学习如何定义自己的异常,并处理这类异常。
自定义远程对象异常,其实很容易实现,只需要继承RemotingException和ISerializable即可,然后使用常规的try..catch就可以捕获这个异常了。需要注意的是要实现一个反序列构造函数,(对于密封类,请使构造函数成为私有;否则,请使构造函数成为受保护),否则会出现“未找到反序列化“xxx”类型对象的构造函数。自定义远程对象异常MyRemoteException.cs
代码如下:
using System;
using System.Runtime.Remoting;
using System.Runtime.Serialization;
namespace RemotingClass
{
[Serializable]
public class MyRemoteException : RemotingException, ISerializable
{
private Exception excep;
public MyRemoteException()
{
excep = new Exception();
}
public MyRemoteException(string excmsg)
{
excep = new Exception(excmsg);
}
public override Exception GetBaseException()
{
return excep.GetBaseException();
}
public override string ToString()
{
return excep.ToString();
}
public override string Message
{
get { return excep.Message; }
}
//申明一个protected的反序列化构造函数,否则会出现“未找到反序列化“xxx”类型对象的构造函数
protected MyRemoteException(SerializationInfo info, StreamingContext context)
{
excep = (Exception)info.GetValue("excep", typeof(Exception));
}
//实现Iserializable接口的GetObjectData方法
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("excep", excep);
}
}
}
远程对象类:
using System;
namespace RemotingClass
{
public class Message : MarshalByRefObject
{
public Guid MessageId { get; set; }
public Message()
{
this.MessageId = Guid.NewGuid(); }
public void ShowTime()
{
Console.WriteLine("Current Time is:" + System.DateTime.Now.ToString());
throw new RemotingClass.MyRemoteException("我发生异常了!"); //抛出一个自定义异常
}
}
}
客户端代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
namespace Client
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Client Started!");
HttpClientChannel channel = new HttpClientChannel();
ChannelServices.RegisterChannel(channel, false);
RemotingClass.Message msg = (RemotingClass.Message)Activator.GetObject(typeof(RemotingClass.Message), "http://localhost:20001/Message.rem");
try
{
msg.ShowTime();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadLine();
}
}
}
实现服务端代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
namespace Server
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Host Started!");
HttpChannel channel = new HttpChannel(20001);
ChannelServices.RegisterChannel(channel, false);
RemotingConfiguration.RegisterWellKnownServiceType(typeof(RemotingClass.Message), "Message.rem", WellKnownObjectMode.SingleCall);
Console.Read();
}
}
}
编译以上代码,生成程序,然后先运行服务器端程序,在运行客户端程序。我们可以看到客户端可以正确捕获远程对象抛出的异常了。(注意:要看到这个效果,要直接运行生成的程序,不要直接在VS.Net里Debug这些代码)