我想使用WCF将Action或Func对象从C#客户端传输(并执行)到C#服务器应用程序。
这是我的代码:
[ServiceContract]
interface IRemoteExecuteServer
{
[OperationContract]
void Execute(Action action);
}
class RemoteExecuteServer : IRemoteExecuteServer
{
public void Execute(Action action)
{
action();
}
}
Servercode:
class Program
{
static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof(RemoteExecuteServer), new Uri("net.tcp://localhost:8000")))
{
host.AddServiceEndpoint(typeof(IRemoteExecuteServer), new NetTcpBinding(), "RES");
host.Open();
Console.WriteLine("Server is running!");
Console.WriteLine("Press any key to exit...");
Console.ReadKey(true);
host.Close();
}
}
}
Clientcode:
class Program
{
static void Main(string[] args)
{
IRemoteExecuteServer server = new ChannelFactory<IRemoteExecuteServer>(new NetTcpBinding(), new EndpointAddress("net.tcp://localhost:8000/RES")).CreateChannel();
server.Execute(delegate()
{
Console.WriteLine("Hello server!");
});
}
}
当执行“server.Execute”行时,我得到一个CommunicationException。 有谁知道如何解决这个错误?
感谢您的帮助!
答案 0 :(得分:1)
我会想到两种解决方案,两者都非常疯狂。主要是因为你发送代码到服务器执行的请求是人们每天都做的事情(我认为没有人做过这样的事情)。
DLL解决方案: 将代码编译为单独的DLL。将此DLL作为流发送到服务器。使用此DLL上的服务器上的反射加载一些带接口的类。然后,您可以在创建的类中运行代码。
代码解决方案: 基本与第一个相同,但不是发送预编译的DLL,而是将代码作为字符串发送,然后使用编程C#编译器编译并运行该代码。
但是您仍然无法从任何函数中提取代码。请记住,Action只不过是对程序集中硬编码函数的委托(引用)。
答案 1 :(得分:0)
是我提出的类似问题。
我也把它链接起来,因为eric lippert展示了如何实现这样的解决方案。
然而,这是一项不错的工作。
答案 2 :(得分:0)
可能存在现有解决方案,我不知道。 (有一些非常漂亮的运行时字节码注入/操作工具,所以...)
但是如果有足够的权限(和信任级别! - 这是一个很大的权限),可以在运行中进行编译和/或在网络上发送各种自我评估表达式(这与发送字节码不同)本身,虽然理论上可以在提取字节码或等价物的情况下完成。)
上述方法不会发送Action&lt; ...&gt;,这需要字节码提取进行序列化(包括捕获上下文,如果有的话),而是像Compiling C# on the Fly那样的你可以进行有趣的讨论,最后找到CodeDOM。
另一方面,LINQ使用Expression trees“解决”字节码提取/反编译的问题。请注意,它不会通过字节码发送,而是使用此方法来允许远程执行表达式树(常见的是SQL查询)。