我试图在.NET远程处理,试图在.NET中复制一个VB6 ActiveX EXE。
到目前为止,我在服务器上实例化了一个单例,所有客户端都可以共享。
单例接受来自客户端的请求并验证数据,以事件的形式返回经过验证的数据。这很好用 - 请求引用Singleton的类会触发它们的事件 - 即它们发送数据,接收验证数据。
但是,我需要一个接口。客户端托管在WPF应用程序中(服务器也是如此),当他们接收数据时,我需要更新显示(文本框,列表框等),以反映客户端和sinlgleton之间的通信。
但是,一旦我在主窗体中添加了一个事件,客户端一旦收到Singleton的回复就会调用我遇到运行时错误,抱怨主窗口没有序列化属性....
为了保持这种简洁,我将按如下方式描述该过程
服务器使用代码运行:
BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();
BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
//
IDictionary myDictionary = new Hashtable();
myDictionary["name"] = String.Format("PracticonChannel_{0}", Port);
myDictionary["typeFilterLevel"] = TypeFilterLevel.Full;
myDictionary["port"] = Port.ToString();
serverProvider.TypeFilterLevel = TypeFilterLevel.Full;
http = new HttpChannel(myDictionary, clientProvider, serverProvider);
// Register RemotingShared.SingletonObject as a
// Singleton Server-Activated type.
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(Practicon.RemotingShared.UploadObjectSingleton), // Server-activated type
"SingletonService", // objectUri
WellKnownObjectMode.Singleton // Singleton instancing mode
);
RemotingConfiguration.ApplicationName = " Upload Server";
RemotingConfiguration.RegisterActivatedServiceType(
typeof(Practicon.RemotingShared.UploadObjectSingleton));
客户端通过以下方式获取服务器激活的单例:
HttpChannel http1;
// Set the formatters of the messages for delivery.
BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();
BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
//
IDictionary myDictionary = new Hashtable();
myDictionary["name"] = String.Format("PracticonChannel_{0}", Port);
myDictionary["typeFilterLevel"] = TypeFilterLevel.Full;
myDictionary["port"] = port.ToString();
serverProvider.TypeFilterLevel = TypeFilterLevel.Full;
http1 = new HttpChannel(myDictionary, clientProvider, serverProvider);
ChannelServices.RegisterChannel(http1, false);
uploadObj= (UploadObjectSingleton)Activator.GetObject(
typeof(UploadObjectSingleton),
fullAddress);
//---------- Here's the problem...
uploadObj.ReplyEvent += new UploadObjectReplyEventHandler(OnUploadReply);
OnUploadReply是一个Form实现的事件,用于更新各种控件。在运行时分配时,由于主窗体缺少序列化属性,会发生序列化异常。
这让我疯了。有人可以向我展示/解释/讲述/讲道/讲授我如何更新用户界面以响应在单身内发射的事件吗?
答案 0 :(得分:1)
好的,这个问题的答案就是使用WCF。它并不像听起来那么可怕,我的解决方案比我预期的更好。
我会向那些试图做我所面对的事情的人强调的是:
显然,创建一个服务器应用程序来托管AND ONLY HOST服务。我尝试过做一些奇特的事情,例如使用服务器应用来维护服务的用户界面 - 状态,它正在做什么以及为谁/为谁。别!。不要。
只有在需要时才打开客户端和服务器之间的连接。任何更长的时间和渠道都有发生故障的风险,经过几个小时试图解决这个问题,试图从失败中恢复过来,你最好试着写一些关于如何对猫群的说明。重新思考你的问题。打开,使用,关闭。
无论如何,我不得不想出一个具有UI的ActiveX控件的替代品。我创建了3个项目 - 服务器(用于托管),客户端(用于为服务提供用户界面)和与服务交互的COM接口(称为函数,设置属性等)和外部应用程序。
COM接口必须做的第一件事就是尝试查找服务器的运行实例(顺便说一句,实现WPF应用程序的单个实例绝非易事,但这不是主题)
如果找不到,则执行Server应用程序,等待然后打开一个频道。每次COM接口必须通话/等待接口时,都会重复此过程(显然,Server应用程序只需运行一次)。一个球疼,但这避免了可怕的'通道处于故障状态'综合征。以前,我会发现该服务可以托管,并且一个频道保持开放一段时间 - 一分钟,一小时,一天,但即使客户端/服务器什么都不做,也会发生错误。由于我的服务是控制北美(来自英国)的生产线,如果界面发生故障,NOTHING会再次运行,我的优先事项是稳定性。因此,“摇滚”和“艰难”这些词语令人不可思议地浮现在脑海中
所以,重复,打开,使用,关闭。
希望这有帮助。
MM
BTW我对Blam的建议表示赞同。