科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道[冷枫]Remoting的事件机制

[冷枫]Remoting的事件机制

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

Remoting的事件机制(带具体例子)

作者:冷枫 来源:CSDN 2007年9月23日

关键字:

  • 评论
  • 分享微博
  • 分享邮件

在本页阅读全文(共2页)

客户端为了简单一点,我去除了前面做测试的本地事件:
using System;
using System.Net;
using System.Collections;
using System.Text;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Serialization.Formatters;

class MyClient
{
    
private delegate int MyDelegate(int a,int b,int time,string ip);
    
private static MyDelegate md;

    [STAThread]
    
static void Main(string[] args)
    {
        DateTime dt
=DateTime.Now;
        RemotingConfiguration.RegisterWellKnownClientType(
typeof(RemoteObject.MyObject), "tcp://localhost:9999/RemoteObject.MyObject");
        BinaryServerFormatterSinkProvider serverProvider 
= new BinaryServerFormatterSinkProvider(); 
        BinaryClientFormatterSinkProvider clientProvider 
= new BinaryClientFormatterSinkProvider(); 
        serverProvider.TypeFilterLevel 
= TypeFilterLevel.Full; 
        IDictionary props
=new Hashtable(); 
        props[
"port"]=0
        TcpChannel channel 
= new TcpChannel(props,clientProvider,serverProvider); 
        ChannelServices.RegisterChannel(channel); 
        RemoteObject.MyObject app
=new RemoteObject.MyObject();
        app.MyEvent
+=new RemoteObject.MyObject.MyEventHandler(MyEvent);
        md
=new MyDelegate(app.ALongTimeMethod);
        AsyncCallback ac
=new AsyncCallback(MyClient.CallBack);
        IPHostEntry ipHE
=Dns.GetHostByName(Dns.GetHostName());
        IAsyncResult Iar
=md.BeginInvoke(1,2,300,ipHE.AddressList[0].ToString(),ac,null);
        Method();
        Console.WriteLine(
"用了"+((TimeSpan)(DateTime.Now-dt)).TotalSeconds+"");
        ChannelServices.UnregisterChannel(channel);
        Console.ReadLine();
    }

    
public static void CallBack(IAsyncResult Iar)
    {
        
if(Iar.IsCompleted)
        {
            Console.WriteLine(
"结果是"+md.EndInvoke(Iar));
        }
    }

    
public static void MyEvent(object sender,RemoteObject.MyEventArgs e)
    {
        Console.WriteLine(
"来自"+e.IP+"的异步方法完成了"+e.Rate*10+"%");
    } 

    
public static void Method()
    {
        Console.WriteLine(
"主线程方法开始");
        System.Threading.Thread.Sleep(
5000);
        Console.WriteLine(
"主线程方法结束");
    }
}

代码看上去不错,可是debug启动后报错:
 
这就是我前面提到的问题,远程不可能有本地的程序集,也无法触发本地事件。解决办法就是加一个事件中间件,继承MarshalByRefObject:
public class EventClass:MarshalByRefObject
    {
        
public void MyEvent(object sender,MyEventArgs e)
        {
            Console.WriteLine(
"来自"+e.IP+"的异步方法完成了"+e.Rate*10+"%");
        } 
    }

然后来修改一下客户端:
把app.MyEvent+=new RemoteObject.MyObject.MyEventHandler(MyEvent);修改为
RemoteObject.EventClass ec=new RemoteObject.EventClass();
        app.MyEvent
+=new RemoteObject.MyObject.MyEventHandler(ec.MyEvent);
删除客户端的MyEvent静态方法。

运行一下程序:


前后两个窗口本别是服务端和客户端的,貌似达到了我们的要求,其实不然,程序有2个漏洞:
1、客户端关闭以后打开新的程序就出错,因为以前的委托链丢失,服务端程序企图触发事件出错。
2、同时打开几个客户端,客户端收到的是所有的进度信息,而不仅仅是自己的,广播性质的消息。


Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=727809

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章