Используйте Threads и сетевой компьютер для выполнения большей части работы с использованием xml-rpc - PullRequest
0 голосов
/ 15 марта 2012

Я разрабатываю приложение, которое, кажется, может быть перегружено определенными функциями, которые должны произойти. По сути, в некоторой части приложения преобразование должно происходить на локальном компьютере в сценариях оболочки, что может занять очень много времени, «до 10 минут» для пользовательских объектов. Таким образом, пользователю не придется ждать, чтобы покинуть страницу, потому что ответ от сервера займет много времени, я думал о двух подходах, которые могли бы устранить эту проблему.

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

public void RunShellScripts(string apppath, string fileargs)
{
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.FileName = apppath;
p.StartInfo.Arguments = fileargs;
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = false;
p.StartInfo.RedirectStandardOutput = false;
p.Start();
//after this is done the converted file would be saved in this current directory
//which is the in the value of the fileargs variable
}

Кроме того, чтобы машина, на которой размещен веб-сервер, не пыталась обрабатывать столько процессов одновременно, еще одна идея заключается в том, чтобы сетевой компьютер получал xml rpc от веб-сервер, чтобы сделать преобразование файла. Таким образом, в основном веб-сервер получает объекты, затем отправляет xml rpc на сетевой компьютер для выполнения преобразования и отправляет преобразованный файл обратно на хост-компьютер. Я также знаком с xml-rpc, но не уверен, смогу ли я отправить его обратно. Примечание: файлы могут быть до 1 ГБ. Мой опыт только посылал результаты и только на другом языке, кроме C #.

Ответы [ 4 ]

0 голосов
/ 27 марта 2012

Если вы хотите сделать это без xml-rpc, вы можете попробовать следующее:

  1. Создать поток, чтобы начать процесс преобразования.
  2. Подождите, пока процессвыход.
  3. Создайте событие после завершения процесса, чтобы вы могли выполнить любые операции с результатом.

       //step 1. To create a thread in .Net 2.0 and higher you could use the
       //ParameterizedThreadStart delegate. For example
    
        Thread t = new Thread (new ParameterizedThreadStart(RunShellScripts));
    
        Hashtable args = new Hashtable();
    

    // вы можете использовать любую другую технику, которая вам нравитсядля инкапсуляции параметров

    hashtable[1] = apppath;
    hashtable[2] = fileargs;
    
        t.Start (args);
    
        static void RunShellScripts(object args)
        {
         //code to start the process
         //step 2. Wait for the process to exit
         while (!shellProcess.HasExited)
         {
            //call sleep (Thread.sleep()) or just do nothing
         }
         //step 3. raise event to notify the end of process.
         //shellProcess.ExitCode can tell you if the process exited with error or not
        }
    
0 голосов
/ 20 марта 2012

Обычно существует более одного способа скинуть кошку:)

Проект, над которым я работаю с нашим клиентом, недавно был запущен.Часть этого приложения влечет за собой преобразование документов в TIFF.Поскольку это также веб-приложение, есть некоторые сходства с тем, чего вы пытаетесь достичь.

Однако мы использовали мою служебную шину с открытым исходным кодом (http://shuttle.codeplex.com/), хотя любая служебная шина будет делать, или вы могли быпрокрутить что-нибудь, используя некоторый механизм организации очередей.

В результате происходит преобразование копируемого файла в некоторый общий файловый ресурс. Это выполняется через нашу службу приложений DocumentConverter.Submit(source, outputMimeType). Затем, все еще являясь частью вызова службы приложения,команда ConvertDocumentCommand отправляется по служебной шине. Команда направляется на преобразователь, и вызывающий абонент продолжает выполнять все свои действия.

Конечная точка преобразователя получает команду, содержащую соответствующие данные (например,в качестве имени файла) в очереди и использует файл в общей папке для выполнения преобразования с использованием стороннего преобразователя. После завершения преобразования конечная точка преобразователя публикует DocumentConvertedEvent или при сбое DocumentConversionErrorEvent.

Отправитель имеет конечную точку, которая подписывается на два события и преобразованный документИспользуется, если доступно.Для нас преобразованный документ помещается в подпапку output общего файлового ресурса, к которому идут входные документы.

Это может показаться несколько запутанным, но это работаеточень хорошо, поскольку наша конечная точка конвертера просто занимается конвертированием документов и публикацией результатов конвертации.Он блаженно не знает о любых других приложениях.

0 голосов
/ 22 марта 2012

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

Очереди сообщений

Посмотрите на RabbitMQ:

После запуска сервера клиент может отправлять и получать сообщения: веб-сервер отправляет сценарий, сервер обработки получает сообщение, а затем отправляет еще одно сообщение.

Вот «Hello World» в Java:http://www.rabbitmq.com/tutorials/tutorial-one-java.html

Документация по клиенту C #: https://github.com/rabbitmq/rabbitmq-tutorials/tree/master/dotnet

Несколько других ресурсов о клиенте C #:

Распределенные вычисления

Это может быть излишним, но масштабируемым.Страница википедии о грид-вычислениях .

NGrid является «платформно-независимой структурой грид-вычислений, написанной на C #».Вот пример Distributed sort .Вы можете распределить обработку по сетке из N узлов, а затем использовать результат.

Wcf

Я не так часто использовал WCF, и мой небольшой опыт работы с ним был довольно раздражающим.Вы можете углубиться в это, но я не уверен, что это служит вашим целям.

Одна ссылка, однако, может быть полезна для передачи больших кусков данных: Как: включить потоковую передачу

Альтернативы

Возможно, будет достаточно простого удаленного взаимодействия или обмена сообщениями через сокет.Это зависит от множества факторов: требуемой масштабируемости, вычислительной мощности, ... Но очередь сообщений выглядит как путь для изучения.

Надеюсь, вы найдете ее полезной.

0 голосов
/ 20 марта 2012

Кажется, что все, что вам нужно - это параллельная Task, которая либо запускает сценарии оболочки на локальном компьютере, либо отправляет запрос XML-RPC на другой компьютер. Вы также можете зарегистрировать обратный вызов, чтобы уведомить родительский поток о том, что работа была завершена:

SendOrPostCallback callback = o => Console.WriteLine((string) o));
SynchronizationContext context = SynchronizationContext.Current;

Task t = Task.Factory.StartNew(
           () =>
           {
               RunShellScripts(); // maybe also parallelize this method
               // or XML-RPC
               context.Post(callback, "Work finished!");
           });

Конечно, код обратного вызова может быть любым, я просто напечатал здесь сообщение.

Я работал с XML-RPC некоторое время назад, но, честно говоря, я мало что помню. Я надеюсь, вы знаете, как справиться с этой частью.

...