【问题标题】:Remote executing of Action<> or Func<> objects远程执行 Action<> 或 Func<> 对象
【发布时间】:2010-10-16 09:06:17
【问题描述】:

我想使用 WCF 将 Action 或 Func 对象从 C# 客户端传输(并执行)到 C# 服务器应用程序。

这是我的代码:

[ServiceContract]
interface IRemoteExecuteServer
{
    [OperationContract]
    void Execute(Action action);
}

class RemoteExecuteServer : IRemoteExecuteServer
{
    public void Execute(Action action)
    {
        action();
    }
}

服务器代码:

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();
        }
    }
}

客户代码:

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

感谢您的帮助!

【问题讨论】:

    标签: c# wcf network-programming


    【解决方案1】:

    我会想到两种解决方案,它们本质上都很疯狂。主要是因为您将代码发送到服务器以执行的请求并不是人们每天都会做的事情(而且我认为没有人做过这样的事情)。

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

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

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

    【讨论】:

    • 所以你也认为我想做的事情不可能像我展示的那样,或者你不知道如何做到这一点。编译到 DLL 或类似的东西对我来说不是一个选项。
    • 就像我说的。 Action 或 Func 不是对象,它是对函数的引用。只需将 Action 视为功能。您可以将函数发送到服务器执行吗?不,你不能。至少不是你认为可以的。
    • 所以你基本上一个函数不是一个“真实”的对象?
    • 在 C# 中不应该一切都是对象吗!?
    • 所有事物都可以表示为对象(请参阅您的操作)。但是只有很少的一般对象可以做(基本上什么也做不了)。在您的情况下,您需要您的对象实现 ISerialisable (或类似的东西),以便可以将其转换为文本友好的形式,通过网络发送,然后重新构造回对象。函数没有这样的能力。主要是因为它们是可执行文件的组成部分,不能轻易从中提取。
    【解决方案2】:

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

    是我问的类似问题。

    我也给你链接了它,因为 eric lippert 展示了这样的解决方案是如何可能的。

    但它的工作量相当可观。

    【讨论】:

      【解决方案3】:

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

      但是如果有足够的权限(和信任级别!——这是一个很大的),一个人可以在运行中编译和/或通过网络发送各种自我评估表达式(这与发送字节码不同) , 本身, 虽然理论上可以这样做, 如果可以提取字节码或等效项)。

      上述方法不会发送 Action<...>,这将需要提取字节码以进行序列化(包括捕获上下文,如果有的话),而是像 Compiling C# on the Fly 这样您可以遵循有趣的讨论,终于找到CodeDOM

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-12-12
        • 1970-01-01
        • 1970-01-01
        • 2012-07-05
        • 2023-03-25
        • 2023-03-04
        • 2015-02-09
        相关资源
        最近更新 更多