你可以看下委托序列化和表达式树序列化相关的内容。
嗯,关键就是委托序列化。高人就是高人啊。谢谢指明方向。
委托是可以序列化了。但是,发送到远程机后。没有委托的运行环境。也反序列化不了。请问有什么思路啊。谢谢
@Sago: 你得看表达式树的序列化内容。但是不管是委托还是表达式树,都有局限性。正如你说的,缺乏对应的上下文环境,比如其中使用到了某个类,那么远程也必须有此类,因此如果你想要跨应用程序域传递委托,那么你必须在两者之间具有相同的上下文环境。我给你举个再灵活的例子,就是 Java Script,你想要的委托序列化后能在远程执行,同在远程执行 JS 是一样的,JS 是解释性语言,它可以跨进程传递源码,但是,并不代表它就能在任何远程环境下都能正确执行,因此它还不是脱离 OS 的独立解释语言,因此,它需要调用一个些 OS 的 API 来实现功能(我们经常碰到的浏览器兼容性问题就包括这部分内容),如果你要实现你的目的,那么 OS 的 API 也要是可以序列化的,目前来看这是不可能的。
@Launcher: 关于上下文环境的问题。我能确保的就是远程机器和客户端机器是具有同样.Net CLR的。我的想法就是远程机器只是少了客户机器自定义的那些DLL。有人跟我说可以使用RCP远程调用协议。我查了一下。好像这是在远程机器调用客户机的方法。还有一个想法就是委托是指向内存的。那么我是否可以共享内存,类似于分布式缓存的机制。又或者是我在远程机器构造一个运行环境,毕竟都是基于同样的.Net CLR,我最终想得就是既然运行平台一样,我的服务器就只是少了一部分自定义的DLL。我能将这些DLL发到服务端,然后构建一个同样的运行环境吗?谢谢。
@Sago: 如果你能把委托涉及的 dll 都发布到远程服务器,那么你可以使用表达式树或脚本的形式来传递你的代码逻辑。即使这样,场景使用也是有限的,对于脚本语言来说,它没有状态,因此可以远程执行,而动态语言不一样,它有执行上下文,对于执行上先文而言,有可能会很复杂,比如涉及到线程、锁等对象时。这部分内容你可以学习下编译原理。
其实在动态语言中执行脚本语言(比如魔兽世界就是采用的 C++ 嵌入 Lua 脚本,由 Lua 脚本来驱动 UI)就能实现你的大多数需求,但是,如果你用脚本来实现你的大多数业务逻辑,那么你就需要重写你的程序,小心的避开不可复制的上下文环境。
泛泛而谈没有用,你只是想法,没有理论知识支撑,你可以举个例子,写段代码来描述你想传递啥,然后我告诉你能,还是不能,以及为什么不能。
PS:共享内存是针对同一台操作系统上的技术,不能用在这里。分布式缓存的各个客户端不用关心缓存服务器的地址空间,而采用共享内存时,各进程必须引用相同的地址空间。这部分内容,建议你学习下操作系统。
@Launcher: 谢谢。听你说,我觉得自己现在还有好多东西要学。其实我是想做一个计划任务平台。我先将一个任务信息(包括执行时间,执行间隔等等信息、具体处理的业务逻辑。)二进制序列化发送到远程服务端。假设这个任务就是备份数据的操作。不用Windows计划任务是因为,我想,我发给远程服务器什么逻辑代码,它就有计划的执行什么代码。不过这个东西不着急。也许以后有人写出一个,或者是我自己写出一个。总之很感谢你教导的东西。谢谢。以后有高深的问题,还得多多向你请教啊。
@Sago: 你这个需求很简单,不用什么委托之类的,就是写一个简单脚本解释解释器或协议解释器。我给你举个例子,比如 SMTP 功能,客户端发送一条一条的指令,服务端对指令做出解释并执行同指令匹配的方法,你的业务逻辑可以制作成一个单一的 DLL,随同指令上传给服务器,类似 SMTP 的附件,你这个比 SMTP 附件多一步的功能就是,上传成功后,服务端需要加载 DLL,然后根据指令来调用你这个 DLL 中的对应方法。这种模式早就在使用中了,而且更进一步的,还可以直接上传代码,服务器先编译,然后执行,现在的云计算平台都这么干。
所以你的需求根本不涉及到远程传递执行上下文,没那么复杂。
@Launcher: 哦,原来是这样啊。我去试试SMTP。谢谢你给了一个方向。万分感激。
@Launcher: 你看新闻了吗?微软成立了一个开源基金会。里面有个项目
明白这两个东西is what
没明白。求进一步指导。
最简单就是用反射,把你的程序集传输到远程然后反射运行指定方法.
比较好的方法是部署一个脚本服务器..net的脚本运行叫撒来着```给忘记了.是一个可以直接执行一个代码字符串的东西.
你可以百度下
你说的反射的方式太麻烦,脚本的这个好像比较靠谱。谢谢。我去查查。
看看Remoting能不能解决你的问题。
Thanks for you reply.我觉得此问题的关键点,在于委托的序列化问题。已经有高人指出了。
呵呵,解决了搞告诉下
目前也只是一个想法咯。委托确实可以序列化和反序列化。
var binaryFormatter = new BinaryFormatter(); var student = new Student() { Name = "Sago" }; using (var fileStream = new FileStream(@"F:\temp.dat",FileMode.OpenOrCreate, FileAccess.ReadWrite)) { binaryFormatter.Serialize(fileStream, student); } Student deserializeStudent; using (var fileStream = new FileStream(@"F:\temp.dat", FileMode.OpenOrCreate, FileAccess.ReadWrite)) { deserializeStudent = binaryFormatter.Deserialize(fileStream) as Student; } deserializeStudent.Action(); [Serializable] public class Student { public string Name { get; set; } public Action Action { get { return () => { this.Name = "Gibbs"; }; } } }
这种简单的委托确实直接执行,但是复杂的我就不知道了。