Удаленное выполнение объектов Action <> или Func <> - PullRequest
1 голос
/ 16 октября 2010

Я хотел передать (и выполнить) объект Action или Func из клиента C # в приложение сервера C # с помощью WCF.

Вот мой код:

[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 ]

1 голос
/ 16 октября 2010

Я бы подумал о двух решениях, оба из которых довольно сумасшедшие по своей природе. Главным образом потому, что ваш запрос на отправку кода на сервер для выполнения - это то, что люди не делают каждый день (и я думаю, что никто никогда не делал ничего подобного).

  1. Решение DLL: Скомпилируйте ваш код в отдельную DLL. Отправить эту DLL в качестве потока на сервер. Загрузите некоторый класс с интерфейсом, используя отражение на сервере из этой DLL. Затем вы можете запустить код в созданном классе.

  2. Кодовое решение: По сути то же самое, что и первый, но вместо того, чтобы отправлять предварительно скомпилированную DLL, вы просто отправляете свой код в виде строки, а затем используете программный компилятор C # для компиляции и запуска этого кода.

Но вы все еще не можете извлечь свой код из любой функции. И помните, что Action - это не что иное, как делегат (ссылка) для жестко закодированной функции в вашей сборке.

0 голосов
/ 19 октября 2010

Там могут быть существующие решения, я не знаю.(Есть несколько довольно изящных инструментов внедрения / манипуляции с байт-кодом во время выполнения, так что ...)

Но при наличии достаточных разрешений (и уровня доверия! - это большое) можно скомпилироватьна лету и / или отправлять различные выражения самооценки по сети (это отличается от отправки байт-кода, как такового, хотя это теоретически можно сделать, если байт-код или его эквивалент можно извлечь).

Приведенные выше подходы не будут отправлять Action <...>, которая потребует извлечения байт-кода для сериализации (включая захват контекста, если есть), а скорее что-то вроде Компиляция C #на лету , за которым вы можете перейти к интересному обсуждению и, наконец, найти CodeDOM .

С другой стороны, LINQ "решает" проблему извлечения байт-кода / де-компиляция с использованием деревьев выражений .Обратите внимание, что он не передает байт-код, а использует этот метод, чтобы разрешить удаленное выполнение деревьев выражений (распространенным является SQL-запрос).

0 голосов
/ 16 октября 2010

Я хочу использовать лямбда-выражение для указания диапазона значений, возвращаемых через службу wcf.

- аналогичный вопрос, который я задал.

Я также связываю вас с этим, поскольку Эрик Липперт показал, как такое решение было бы возможно.

Однако это достойный объем работы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...