Remoting异步事件问题

slin60 2009-02-17 11:18:29
我有一ftp操作类,采用remoting方式在服务器端发布。
当ftp操作类进行异步上传或者异步下载时,会触发相应的事件(主要用来控制客户端的进度条)。

问题是怎样才能让客户端订阅到相应的ftp事件。(客户端订阅服务器的事件)
采用中间事件类中转只能订阅到同步方法的事件,异步的就不顶用,不报错,也不触发事件。


这个问题不解决我寝食难安啊,请各位帮忙~~~如果觉得我问题没描述清楚,大家可以提出来,我详细描述一下。
...全文
330 22 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
wangping_li 2009-02-20
  • 打赏
  • 举报
回复
不想应事件到底是事件没有订阅到还是别的原因?这个要检查一下
slin60 2009-02-20
  • 打赏
  • 举报
回复
真没人知道吗?
david_anwei 2009-02-19
  • 打赏
  • 举报
回复
帮顶!
slin60 2009-02-19
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 guoyichao 的回复:]
触发事件的时候是不是这样的:

public event EventHandler e;

if (e != null) e();

如果是的话,肯定是e为空了才不触发事件,Remoting内部代码很有可能把远程设置的事件委托给卸载了,可以为远程事件做成事件属性来避免内部代码移除事件委托:

private event EventHandler e;
publice event EventHandler p
{
add { e += value; }
remove { }
}

至于Remoting内部为什么会把远程委托的事件移…
[/Quote]


没注意过,下午找个时间试试。大家还有其他注意吗?实在不行的话,我准备结贴了
guoyichao 2009-02-19
  • 打赏
  • 举报
回复
触发事件的时候是不是这样的:

public event EventHandler e;

if (e != null) e();

如果是的话,肯定是e为空了才不触发事件,Remoting内部代码很有可能把远程设置的事件委托给卸载了,可以为远程事件做成事件属性来避免内部代码移除事件委托:

private event EventHandler e;
publice event EventHandler p
{
add { e += value; }
remove { }
}

至于Remoting内部为什么会把远程委托的事件移除就要问微软了。
slin60 2009-02-19
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 hetl_1985 的回复:]
在remoting上使用异步回调操作首先确保TypeFilterLevel为Full,其次还要在网络配置上确保服务器能对客户端发起连接。
[/Quote]

这个是肯定的,要是不这样设那就会报错了

我的问题是不报错,也不响应事件
悔说话的哑巴 2009-02-19
  • 打赏
  • 举报
回复
在remoting上使用异步回调操作首先确保TypeFilterLevel为Full,其次还要在网络配置上确保服务器能对客户端发起连接。
slin60 2009-02-18
  • 打赏
  • 举报
回复
代码有点多,实际上异步事件就是WebClient的UploadProgressChanged、UploadFileCompleted事件,我觉得这个在代码中是没有问题的,因为如果我不采用remoting的话,这些事件都工作得很好
netcoder 2009-02-18
  • 打赏
  • 举报
回复
看来楼主只能把你的FTP类简化一下,把相关代码贴出来看看吧
slin60 2009-02-18
  • 打赏
  • 举报
回复
感谢 wangping_li 提供的例子

但问题任然没有解决,你的是同步方法采用异步的方式来执行。

我这个本身就是异步方法~~~。事实上就是WebClient的异步上传、异步下载功能。但不知道为什么就是不能触发异步下载的事件。类似于EventClass 这样的事件中间类我也有啊
wangping_li 2009-02-17
  • 打赏
  • 举报
回复
你可以在RemoteObject类的事件里面写你的下载状态
客户端根据收到的值显示为进度条
wangping_li 2009-02-17
  • 打赏
  • 举报
回复
客户端是:


namespace MyClient
{
class Program
{
private delegate int MyDelegate(int a, int b, int time, string ip);
private static MyDelegate md;
static RemoteObject.MyObject app;
static RemoteObject.EventClass ec;
static DateTime dt;

static void Main(string[] args)
{
dt = DateTime.Now;
RemotingConfiguration.RegisterActivatedClientType(typeof(RemoteObject.MyObject), "tcp://localhost:8888/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);
app = new RemoteObject.MyObject();
ec = new RemoteObject.EventClass();
app.MyEvent += new RemoteObject.MyObject.MyEventHandler(ec.MyEvent);
md = new MyDelegate(app.ALongTimeMethod);
AsyncCallback ac = new AsyncCallback(MyClient.CallBack);
IPHostEntry ipHE = Dns.GetHostByName(Dns.GetHostName());
Random rnd = new Random(System.Environment.TickCount);
string ip = ipHE.AddressList[0].ToString() + "(" + rnd.Next(100000000).ToString() + ")";
app.tmp = ip;
IAsyncResult Iar = md.BeginInvoke(1, 2, 500, ip, 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));
app.MyEvent -= new RemoteObject.MyObject.MyEventHandler(ec.MyEvent);
}
}

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

}
}
wangping_li 2009-02-17
  • 打赏
  • 举报
回复
给你一个异步事件参考:
Service端

//建一个RemoteObject类
using System;

namespace RemoteObject
{
[Serializable]
public class MyEventArgs : EventArgs
{
private int _rate;
private string _ip;

public int Rate
{
get
{
return _rate;
}
}

public string IP
{
get
{
return _ip;
}
}

public MyEventArgs(int rate, string ip)
{
this._rate = rate;
this._ip = ip;
}
}

public class MyObject : MarshalByRefObject
{
public delegate void MyEventHandler(object sender, MyEventArgs e);
public event MyEventHandler MyEvent;
public string tmp;

public int ALongTimeMethod(int a, int b, int time, string ip)
{
Console.WriteLine("来自" + ip + "的异步方法开始");
for (int i = 1; i <= 10; i++)
{
System.Threading.Thread.Sleep(time);
Console.WriteLine("来自" + ip + "的异步方法完成了" + i * 10 + "%");
OnMyEvent(new MyEventArgs(i, ip));
}
Console.WriteLine("来自" + ip + "的异步方法结束");
return a + b;
}

protected void OnMyEvent(MyEventArgs e)
{
if (MyEvent != null)
{
foreach (Delegate d in MyEvent.GetInvocationList())
{
try
{
((MyEventHandler)d)(this, e);
}
catch
{
MyEvent -= (MyEventHandler)d;
}
}
}
}
}

public class EventClass : MarshalByRefObject
{
public void MyEvent(object sender, MyEventArgs e)
{
if (((MyObject)sender).tmp == e.IP)
Console.WriteLine("异步方法完成了" + e.Rate * 10 + "%");
}
}
}
二、服务
using System;
using System.Collections;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Serialization.Formatters;

namespace WebService1
{
class Service1
{
[STAThread]
static void Main(string[] args)
{
BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
RemotingConfiguration.ApplicationName = "RemoteObject.MyObject";
RemotingConfiguration.RegisterActivatedServiceType(typeof(RemoteObject.MyObject));
BinaryServerFormatterSinkProvider servERProvider = new BinaryServerFormatterSinkProvider();
BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();
serverProvider.TypeFilterLevel = TypeFilterLevel.Full;
IDictionary props = new Hashtable();
props["port"] = 8888;
TcpChannel channel = new TcpChannel(props, clientProvider, serverProvider);
ChannelServices.RegisterChannel(channel);
Console.ReadLine();
}
}

}
stonehy520 2009-02-17
  • 打赏
  • 举报
回复
帮顶
slin60 2009-02-17
  • 打赏
  • 举报
回复
在remoting上使用异步回调操作首先确保TypeFilterLevel为Full,其次还要在网络配置上确保服务器能对客户端发起连接。

---------------------------

我是能获取远程对象,并且能执行相应的异步上传、下载方法,但就是不能触发异步上传、下载的事件(这样就不能在客户端实现进度条功能)。
网上的对于客户端订阅服务器端事件,都是采用一个中间事件类来实现的。事实上我也是这样做得,并且在同步上传方法上能顺利订阅相应的进度事件。但换成异步方法后就不能执行事件方法了。(能订阅+=,但是不执行订阅的方法)


http://www.cnblogs.com/pursuedream/articles/486036.html参考
-----------------------------------------------------------

这个我看了,ftp类本身其实就已经实现了异步方法。

问题没解决,多谢大家顶起来~~~~
weilong147247943 2009-02-17
  • 打赏
  • 举报
回复
关注+学习!
guoyichao 2009-02-17
  • 打赏
  • 举报
回复
在remoting上使用异步回调操作首先确保TypeFilterLevel为Full,其次还要在网络配置上确保服务器能对客户端发起连接。
yulien 2009-02-17
  • 打赏
  • 举报
回复
CutBug 2009-02-17
  • 打赏
  • 举报
回复
mark学习
加载更多回复(2)

111,095

社区成员

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

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

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