2010-01-14 34 views
1

对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功能包含在它没有任何,但接收args:object o和DataReceivedEventArgs e。

什么方法最好返回e.Data从原始开关(perl_o)显示在消息框中?我不知道如何做到这一点。我甚至不确定是否有用于从外部调用perl的最有效的方法。整个应用程序基于perl被外部调用,并返回数据。调用perl的部分已经在第二个线程上运行。任何和所有的帮助,将不胜感激,因为我是一个初学者...要温柔:)

编辑: e.Data未声明。它在调用事件Perl_Output时传递。交换机用于基本的网络命令,在这种情况下:“PERL_TEST”。

未声明perl_o。我正在寻找一种方法来使perl_o = e.Data AFTER mainproc.process_file完成它的过程。

对我来说最好的总体方法是如果我可以将包含myProcess的函数声明为字符串(而不是void),让函数等待进程完成运行,然后返回进程的输出。

+0

开关测试是什么? – 2010-01-14 14:44:13

+0

我认为你已经消除了太多的代码。我没有看到perl_o或e.Data在您的片段中声明或传递......它们来自哪里?他们如何到达那里?显示你的整个方法将有所帮助。 – 2010-01-14 14:45:30

回答

2

消息是否有要显示在switch语句中?如果是这样,那么你可以使用wait handles或类似的方法来阻塞当前线程,直到数据从新进程返回,但这可能不是最好的方法。

这可能是更明智的回调传递到从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对象。

+0

哇,伙计,谢谢你的包......我每天都从这块板子里学到很多东西。哈哈,如果我知道他们,哇回调会让我的生活变得更容易。 – cam 2010-01-14 14:59:23

+0

你喜欢这个答案?请注意!最后,你可以接受一个给定的答案(当它解决你的问题时)。 – tanascius 2010-01-14 15:02:01

0

在你的类创建一个StringBuilder成员变量和DataReceivedEventHandler,您连接e.DataStringBuilder成员变量,通过调用其Append()方法。

完成后,您可以在StringBuilder对象上调用ToString(),并获得所有输出。

此外,您可能还想为ErrorDataReceived事件做类似的事情。

1

你知道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的应用程序将终止,如果缓冲区已满。阅读必须在第二个线程上完成。