我的问题与C# - Overriding an Event Handler - Adding a parameter
非常相似我尝试了Jon Skeet的建议但是每当我的进程引发事件时,我都会得到一个异常,即没有与该进程关联的对象。如果一个过程引发了这个事件,那怎么可能呢?
我正在开发一个从文本文件中读取计算机列表的程序,然后为每台计算机创建一个启动cmd.exe并运行dir命令以在目标计算机上搜索某个文件的进程。这是我的一些代码。请原谅我的混乱,我经常写东西,遇到问题,然后在清理之前尝试一堆东西。我还是很陌生。
foreach (var machine in machines)
{
using (Process searcher = new Process())
{
searcher.StartInfo = cmd;
searcher.StartInfo.Arguments = "/C dir \\\\" + machine + "\\c$\\*.pst /a/s";
searcher.ErrorDataReceived += new DataReceivedEventHandler(searcher_ErrorDataReceived);
searcher.Start();
searcher.BeginOutputReadLine();
searcher.BeginErrorReadLine();
if (!searcher.HasExited)
{
searcher.OutputDataReceived += (sender, args) => HandleData(procCount, args);
}
else
{
MessageBox.Show(searcher.StandardOutput.ReadToEnd());
}
}
}
我的HandleData
方法如下所示:
private void HandleData(int ID, DataReceivedEventArgs args)
{
if (this.outputBox.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(HandleData);
this.Invoke(d, new object[] { ID, args });
}
else
{
this.outputBox.AppendText(args.Data);
processes[ID] += args.Data + "\n";
}
}
outputBox
是我写入的Windows窗体对象,它可以工作,但不适用于在脱机计算机上运行命令的进程。行
this.outputBox.AppendText(args.Data);
并且是NullReferenceException
。 args.Data
为空。因此,即使dir通常输出“机器离线”或类似于命令提示符的东西,它也不会将其写入其输出流,而且我不知道如何解决这个问题。
我的主要问题是:如何在不丢失现有异步读数的情况下将每个进程的输出保持在一起?每个进程都需要启动,执行它的事情,然后它写入自己的输出流的每一行都需要保存在一起,这样我就可以将它全部读回来。
答案 0 :(得分:0)
经过一段时间的实验,我重写了我的代码。我创建了一个类,它接受一个计算机名称,但也跟踪输出,错误并处理将运行CMD的进程。在我的表单对象中,我使用了一个每个搜索器对象的一个线程,这样每个搜索者都可以搜索并等待其相关进程退出,然后再处理它而不占用程序的其余部分。
我的主要问题是找到在这种情况下使用的模式。它与观察者类相反,因为我有许多主题(搜索者)和只有一个听众(表单)。我最后只创建了一个ProgressEventArgs类,并在与每个搜索器关联的进程启动或停止时引发事件。我创建了一个自定义的退出事件,用于何时退出与每个搜索者关联的进程(表单订阅),以便表单可以计算已完成的搜索者数量,并在所有搜索完成后读取所有输出。
我不禁想到我可能已经介绍的所有冗余或我可以使用的现有方法,但你不能使用你不知道的东西。感谢Simon的帮助!