请教关于Remoting的一个问题

reformer 2003-10-15 03:07:30
我的远程对象代码如下:
using System;

namespace RemoteObject
{
/// <summary>
/// Class1 的摘要说明。
/// </summary>
///
public delegate void MyEventHandler(object sender,MyEventArgs ev);

public class MyRemoteObject:System.MarshalByRefObject
{
public event MyEventHandler protest; //定义一个事件
public MyEventArgs ee;
public MyRemoteObject()
{
try
{
ee = new MyEventArgs(DateTime.Now.ToString());

this.protest(this,ee);
}
catch(Exception ex)
{
throw new System.Exception(ex.ToString());
}
}
public string Hello()
{
return "Hello, .NET Client!!!";
}
public double NumAdd(double num1,double num2)
{
return num1 + num2;
}
public int NumAdd(int num1,int num2)
{
return num1 + num2;
}
}
}

问题出现在this.protest(this,ee);这句话上
如果去掉这句话,一点事都没有
我加上这句话,是客户端每声明一个远程对象时发生一次protest事件,然后服务器端程序处理一些事务,比如统计访问人数等。
可是提示异常:
“未将对象引用设置倒对象的实例”
我实在查不出来是什么问题。
大家帮我看看问题出在哪里了?
谢谢
...全文
48 31 打赏 收藏 转发到动态 举报
写回复
用AI写文章
31 条回复
切换为时间正序
请发表友善的回复…
发表回复
ffengl 2003-10-31
  • 打赏
  • 举报
回复
我不知我们所说的触发和订阅是不是指同一个意思,好像有点分歧了。

public event SendMessageHandler SendMessage;
照我的理解,客户端触发,那就是在客户端调用FireEvent()函数:
obj.FireEvent()
{
if(SendMessage!=null)
{
SendMessage();
}
}

服务器订阅,那就是在服务器端
obj.SendMessage+=new SendMessageHandler(AnyThingChanged);

private void AnyThingChanged()
{
do something;
}

ffengl 2003-10-28
  • 打赏
  • 举报
回复
只是很奇怪,System.Runtime.Remoting里的操作很受限制,连服务器端的剪贴板里的内容都取不到,深感失望。用socket 可以轻而易举做到的事,在Remoting很容易就会碰壁,不知通过设置可不可以解决。反正感觉,用Remoting很麻烦,还得专门写一个类使之同时存在服务器端和客户端,我以后会慎用的。
ffengl 2003-10-28
  • 打赏
  • 举报
回复
尽管这个帖子已经结了,但还是想说两句。

在客户端,是可以触发事件的。
用以上的例子来说明一下:
A obj=new A();
A.ChangeName("改名字啦","我");
以上代码用来通知事件的发生。

在服务器端,只要订阅了事件
A obj=new A();
obj.SendMessage+=new SendMessageHandler(AnyThingChanged);
那么AnyThingChanged函数里就可以捕捉到在客户端生成的事件。



qimini 2003-10-28
  • 打赏
  • 举报
回复
TO ffengl(峰的意境) :

你误会我的意思了,你再看看我的解释~~~他是想服务器端订阅,客户端触发

另外,你所用到的Remoting可能只局限于表面,其实Remoting是不错的架构---可惜现在不是很成熟。

bindsang 2003-10-17
  • 打赏
  • 举报
回复
protest(this,ee);
把this引用去掉
reformer 2003-10-16
  • 打赏
  • 举报
回复
TO:qimini(循序渐进)
谢谢您了!
qimini 2003-10-16
  • 打赏
  • 举报
回复
昏~~~
触发肯定是服务器本身才可以触发的,响应可以在客户端也可以在服务器端
订阅如果在服务器端的话,那么触发也一定要在服务器端 ,除非你再定义一个委托用来调用客户端的响应代码,实际上很少用到

以下代码展示事件的层次传递

<>服务器端:

构造函数中:
...
obj.protest += new MyEventHandler(this.ListText);

响应事件的处理方法:
public void ListText(...)
{
this.AnotherEvent(...);//触发新的事件,要在服务器端的
}


<>客户端:
构造函数中:

...
obj.AnotherEvent+= new MyEventHandler(this.IsME);//订阅AnotherEvent事件

响应事件的处理方法:
public void IsME(...)
{
MessageBox.Show("调用到我啦");
}

BTW,客户端不会触发事件只能订阅事件和处理事件;而服务器端既能发起、触发、响应也能处理事件


reformer 2003-10-16
  • 打赏
  • 举报
回复
我的本意是:客户端触发事件,服务器订阅事件,

我想实现这样的功能,该如何处理?
qimini 2003-10-15
  • 打赏
  • 举报
回复

MyRemoteObject obj = new MyRemoteObject();
obj.protest += new MyEventHandler(this.ListText);
这段代码要在客户端的,就可以了
其实就是回调

reformer 2003-10-15
  • 打赏
  • 举报
回复
就是这段代码在服务器端上:
MyRemoteObject obj = new MyRemoteObject();
obj.protest += new MyEventHandler(this.ListText);
而下面的在客户端上:
obj.ChkIn()
reformer 2003-10-15
  • 打赏
  • 举报
回复
To:qimini(循序渐进)
我知道原因了!
因为我在服务器上订阅事件,在客户端触发事件,
就是这段代码在:
MyRemoteObject obj = new MyRemoteObject();
obj.protest += new MyEventHandler(this.ListText);
而:
obj.ChkIn()
这个函数是MyRemoteObject上的一个方法,此方法触发事件!

我的本意是:客户端触发事件,服务器订阅事件,
可能不在同一个程序域的原因!

可是我又想实现这样的功能,该如何处理?
qimini 2003-10-15
  • 打赏
  • 举报
回复
1、定义一个委托

public delegate void SendMessageHandler(String strMessage,String strTarget);

2、定义一个事件绑定到委托

public SendMessageHandler SendMessage;

3、预置事件发生条件

public class A
{
...
public ChangeName(String strAction,String strPerson)
{
...... //此处改名字
if(SendMessage!=null) //可以不做判断
{
SendMessage(strAction,strPerson);
}
}
...
}
4、订阅事件

A obj=new A();
obj.SendMessage+=new SendMessageHandler(AnyThingChanged);
A.ChangeName("改名字啦","我");

5、响应事件的方法
public void AnyThingChanged(String strM,String strO)
{
Console.Write("消息内容:"+strM+"||||消息发送人:"+strO);
}


如果你想由类自己响应事件,可以在构造函数里订阅事件;同时你要写一个申明及定义域和委托相同的方法
reformer 2003-10-15
  • 打赏
  • 举报
回复
TO:qimini(循序渐进)
^_^,改如何订阅事件,我想这个事件由服务器端的一个方法来处理
我的服务器端有个代码
MyRemoteObject obj = new MyRemoteObject();
obj.protest += new MyEventHandler(this.ListText);
qimini 2003-10-15
  • 打赏
  • 举报
回复
实例名.事件名+=new 委托名(实现事件的方法名);
reformer 2003-10-15
  • 打赏
  • 举报
回复
请问:声明一个事件后,我要引发一个事件,中间需要什么操作,比如类,中间需要一个实例化操作,才能操作,那-事件呢?
qimini 2003-10-15
  • 打赏
  • 举报
回复
昏~~~
客户端没有订阅事件???

qimini 2003-10-15
  • 打赏
  • 举报
回复
<configuration>
<system.runtime.remoting>
<application name="Client">
<channels>
<channel ref="tcp" useDefaultCredentials="true" port="0">
<clientProviders>
<formatter
ref="binary"
/>
</clientProviders>
</channel>
</channels>
<client url="tcp://localhost:9000/Server">
<wellknown type="RemoteObject.MyRemoteObject,MyRemoteObject" url="tcp://localhost:9000/Server/MyRemoteObject"/>
</client>
</application>
</system.runtime.remoting>
</configuration>
reformer 2003-10-15
  • 打赏
  • 举报
回复
TO:citymeteor(流星)
用的那个判断后,没有出现异常,看来是我的这个事件没有实例化(事件也需要实例化吗?)
如果我一定要实现的事件,就是一定要引发这个事件,该怎么左?
reformer 2003-10-15
  • 打赏
  • 举报
回复
你用的是http格式通道。我用的是tcp通道
reformer 2003-10-15
  • 打赏
  • 举报
回复
这是我的 Client端的config
<configuration>
<system.runtime.remoting>
<application name="Client">
<client url="tcp://localhost:9000/Server">
<wellknown type="RemoteObject.MyRemoteObject,MyRemoteObject" url="tcp://localhost:9000/Server/MyRemoteObject"/>
</client>
<channels>
<channel ref="tcp client"/>
</channels>
</application>
</system.runtime.remoting>
</configuration>
加载更多回复(11)

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧