远程执行Action<>或者Func<>对象

时间:2010-10-16 09:06:17

标签: c# wcf network-programming

我想使用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。 有谁知道如何解决这个错误?

感谢您的帮助!

3 个答案:

答案 0 :(得分:1)

我会想到两种解决方案,两者都非常疯狂。主要是因为你发送代码到服务器执行的请求是人们每天都做的事情(我认为没有人做过这样的事情)。

  1. DLL解决方案: 将代码编译为单独的DLL。将此DLL作为流发送到服务器。使用此DLL上的服务器上的反射加载一些带接口的类。然后,您可以在创建的类中运行代码。

  2. 代码解决方案: 基本与第一个相同,但不是发送预编译的DLL,而是将代码作为字符串发送,然后使用编程C#编译器编译并运行该代码。

  3. 但是您仍然无法从任何函数中提取代码。请记住,Action只不过是对程序集中硬编码函数的委托(引用)。

答案 1 :(得分:0)

I want to be able to use a lambda expression to specify a range of values to return over a wcf service

是我提出的类似问题。

我也把它链接起来,因为eric lippert展示了如何实现这样的解决方案。

然而,这是一项不错的工作。

答案 2 :(得分:0)

可能存在现有解决方案,我不知道。 (有一些非常漂亮的运行时字节码注入/操作工具,所以...)

但是如果有足够的权限(和信任级别! - 这是一个很大的权限),可以在运行中进行编译和/或在网络上发送各种自我评估表达式(这与发送字节码不同)本身,虽然理论上可以在提取字节码或等价物的情况下完成。)

上述方法不会发送Action&lt; ...&gt;,这需要字节码提取进行序列化(包括捕获上下文,如果有的话),而是像Compiling C# on the Fly那样的你可以进行有趣的讨论,最后找到CodeDOM

另一方面,LINQ使用Expression trees“解决”字节码提取/反编译的问题。请注意,它不会通过字节码发送,而是使用此方法来允许远程执行表达式树(常见的是SQL查询)。