对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。
最好从原始开关(perl_o)返回要在消息框中显示的e.Data的方法是什么?我不知道该怎么做。我甚至不确定我是否有最有效的方法从外部调用perl。整个应用程序基于perl被外部调用,并返回数据。调用perl的部分已经在第二个线程上运行。任何和所有的帮助将不胜感激,因为我是一个初学者...温柔:))
编辑: e.Data未声明。它在调用事件Perl_Output时传递。该交换机用于基本网络命令,在这种情况下:“PERL_TEST”。
未声明perl_o。我正在寻找一种方法来使perl_o = e.Data在mainproc.process_file完成它的过程之后。
对我来说最好的总体方法是,如果我可以将包含myProcess的函数声明为字符串(而不是void),让函数等待进程完成运行,然后返回进程的输出。
答案 0 :(得分: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
对象。
答案 1 :(得分: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应用程序将停止。阅读必须在第二个线程上完成。
答案 2 :(得分:0)
在您的班级和StringBuilder
中创建DataReceivedEventHandler
成员变量,通过调用e.Data
方法将StringBuilder
连接到Append()
成员变量
完成后,您可以在ToString()
对象上拨打StringBuilder
并获得所有输出。
此外,您可能希望为ErrorDataReceived
事件做类似的事情。