Передача возвращенных данных о событии - PullRequest
1 голос
/ 14 января 2010

Довольно плохо знаком с C # (и я бы назвал себя новичком в программировании, но я честолюбив), так что, возможно, это очень простое решение.

У меня есть функция, вызываемая в переключателе, как это:

            case "PERL_TEST":
            FileInfo fi = new FileInfo("hello.txt");
            mainproc.process_file(fi);
            MessageBox.Show(perl_o);                
            break;

mainproc.process - это функция, которая вызывает Perl следующим образом:

myProcess = new Process();
        ProcessStartInfo myProcessStartInfo = new ProcessStartInfo("perl.exe");
        myProcessStartInfo.Arguments = "perly.pl";
        myProcessStartInfo.UseShellExecute = false;
        myProcessStartInfo.RedirectStandardOutput = true;
        myProcessStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
        myProcessStartInfo.CreateNoWindow = true;
        myProcess.StartInfo = myProcessStartInfo;
        myProcess.OutputDataReceived += new DataReceivedEventHandler(Perl_Output);
        myProcess.Start();
        myProcess.BeginOutputReadLine();

Функция Perl_Output ничего не содержит в себе, но получает аргументы: объект o и DataReceivedEventArgs e.

Каким методом было бы лучше вернуть e.Data для отображения в окне сообщения от исходного переключателя (perl_o)? Я не уверен, как это сделать. Я даже не уверен, что у меня есть самый эффективный метод для внешнего вызова Perl. Все приложение основано на том, что perl вызывается извне и возвращает данные. Часть, которая вызывает Perl, уже запущена во втором потоке. Любая и вся помощь будет оценена, так как я новичок ... будьте нежны:)

Edit: е. Данные не объявлены. Он передается, когда вызывается событие Perl_Output. Переключатель для основных сетевых команд, в данном случае: «PERL_TEST».

perl_o не объявлен. Я ищу способ, чтобы perl_o = e.Data ПОСЛЕ mainproc.process_file завершил свой процесс.

Лучший общий способ для меня был бы, если бы я мог объявить функцию, содержащую myProcess, как строку (вместо void), заставить функцию ждать завершения процесса, а затем вернуть выходные данные процесса.

Ответы [ 3 ]

2 голосов
/ 14 января 2010

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

Возможно, было бы разумнее передать обратный вызов в функцию из оператора switch:

case "PERL_TEST":
    FileInfo fi = new FileInfo("hello.txt");
    mainproc.process_file(fi, MessageBox.Show);
    break;

Тогда в process_file:

public void process_file(FileInfo fi, Action<string> dataCallback)
{
    myProcess = new Process();
    ProcessStartInfo myProcessStartInfo = new ProcessStartInfo("perl.exe");
    myProcessStartInfo.Arguments = "perly.pl";
    myProcessStartInfo.UseShellExecute = false;
    myProcessStartInfo.RedirectStandardOutput = true;
    myProcessStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
    myProcessStartInfo.CreateNoWindow = true;
    myProcess.StartInfo = myProcessStartInfo;
    myProcess.OutputDataReceived += (sender, e) =>
        {
            dataCallback(e.Data);
        };
    myProcess.Start();
    myProcess.BeginOutputReadLine();
}

Или что-то похожее на это, так как я не вижу, где вы используете объект FileInfo.

1 голос
/ 14 января 2010

Знаете ли вы, что myProcess.Start () создает процесс, который работает параллельно?

Вы должны собрать выходные данные процесса и дождаться завершения процесса. Я бы сделал это так:

myProcess.Start();
string perl_o, error;
Thread readStandardOutput = new Thread((ThreadStart)delegate 
{ 
    perl_o = myProcess.StandardOutput.ReadToEnd(); 
});  
Thread readStandardError = new Thread((ThreadStart)delegate 
{ 
    error = myProcess.StandardOutput.ReadToEnd(); 
});  

myProcess.WaitForExit();    // wait until the process exits
readStandardOutput.Join();  // wait until the thread has read all data
readStandardError.Join();   // wait until the thread has read all data
int exitCode = p.ExitCode;  // if you need the exit code from perl
return perl_o;

Вы также должны читать из StandardError, потому что, если perl записывает туда что-то, а ваше приложение не читает, приложение perl остановится, если буфер заполнен. Чтение должно быть сделано во втором потоке.

0 голосов
/ 14 января 2010

Создайте StringBuilder переменную-член в своем классе и в DataReceivedEventHandler вы объедините e.Data с вашей StringBuilder переменной-членом, вызвав ее метод Append().

Как только вы закончите, вы вызываете ToString() для вашего StringBuilder объекта, и у вас есть все выходные данные.

Также вы можете сделать то же самое для события ErrorDataReceived.

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