0

我的问题与 C# 非常相似- 覆盖事件处理程序 - 添加参数

我尝试了 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);

并且是一个NullReferenceExceptionargs.Data一片空白。因此,即使 dir 通常输出“机器离线”或类似于命令提示符的内容,它似乎也不会将其写入其输出流,我不知道如何解决这个问题。

我的主要问题是:如何在不丢失我现在拥有的异步读取的情况下将每个进程的输出保持在一起?每个进程都需要开始,做它的事情,然后它写入自己的输出流的每一行都需要保持在一起,这样我就可以完整地读回来。

4

1 回答 1

0

经过相当多的试验后,我重写了我的代码。我创建了一个类,它接受计算机名称,但也跟踪输出、错误并处理将运行 CMD 的进程。在我的表单对象中,我为每个搜索器对象使用了一个线程,这样每个搜索器都可以搜索并等待其关联的进程退出,然后再将其处理掉,而不会占用程序的其余部分。

我的主要问题是找到在这种情况下使用的模式。它有点与观察者类相反,因为我有许多主题(搜索者)和只有一个听众(表单)。我最终只是创建了一个 ProgressEventArgs 类,并在与每个搜索器关联的进程启动或停止时引发事件。我创建了一个自定义的 Exited 事件,用于与每个搜索者关联的进程退出(表单订阅的),以便表单可以计算有多少搜索者已经完成,并在所有搜索者都完成时读取他们的所有输出。

想到我可能引入的所有冗余或我可以使用的现有方法,我不寒而栗,但你不能使用你不知道的东西。感谢西蒙的帮助!

于 2013-06-20T01:00:04.290 回答