【问题标题】:Why do I have two instances of the same processes?为什么我有两个相同进程的实例?
【发布时间】:2018-11-14 06:37:31
【问题描述】:

所以我正在玩我的一个项目,现在导致问题的是当我单击我的 Start 按钮时,此方法运行。

public void Start()
        {
            if (!ServerIsRunning)
            {
                ConsoleOutput.Clear();

                pServer = new Process();
                pServer.StartInfo.FileName = "java";
                pServer.StartInfo.Arguments = @"-jar " + "-Xms512M -Xmx1G myJavaFile.jar";

                pServer.Start();
                PID = pServer.Id;

                counter = new PerformanceCounter("Process", "% Processor Time", pServer.ProcessName, true);

                timer.Interval = TimeSpan.FromSeconds(1);
                timer.Tick += timer_Tick;
                timer.Start();
            }
        }

我已经为 PerformanceCounter 创建了一个全局 null 属性,就像这样

private PerformanceCounter counter;

正如您在 start 方法中看到的那样,我们为它分配了一个值。

我还为更新属性的计时器创建了这个滴答事件

void timer_Tick(object sender, EventArgs e)
        {
            FindServerProcess();
            double pct = counter.NextValue() / 10;
            ServerCPU = pct.ToString("0.0");
        }

这里是里面找到某个PID对应的进程的方法

public void FindServerProcess()
{
    Process[] processes = Process.GetProcesses();
    foreach (var process in processes)
    {
        if (process.Id == PID)
        {
            Console.WriteLine("Found the process!");
        }
    }
}

当我单击“开始”时,它会在“输出”窗口中告诉我它通过打印出消息 Found the process! 来按预期找到进程。

但是.. 这就是奇怪的地方。 如果我点击我的停止按钮

private void Stop(string StopCommand) 
{
     counter.Close();
     counter = null;
     timer.Stop();
     pServer.StandardInput.WriteLineAsync(StopCommand);
}

它关闭计数器,使其为空,然后我停止调用滴答事件的计时器。然后我还向控制台流发出了一个只是stop 的命令,它只是关闭了进程。 此时进程已经关闭,我在任务管理器中看不到它了。 但是,当我单击开始时,它会同时开始两次打印Found the process!,并且它正在更改的属性值似乎是两倍。这是为什么?我没有安全地关闭房产吗?还是我忘记处理一些物品?

【问题讨论】:

    标签: c# .net asynchronous memory process


    【解决方案1】:

    我认为你的两行Found the process! 的问题是由你的Start() 函数引起的,特别是这行:

    timer.Tick += timer_Tick;
    

    正如您所描述的按“开始”、“停止”和“重新开始”的操作。 timer.Tick 事件被添加了两次(每次运行 Start() 函数时一次。

    要反击,只需添加一行

    timer.Tick -= timer_Tick;
    

    事先。

    每当您在运行时添加事件处理程序时,您应该始终在调用之前使用-= 语法删除先前分配的事件处理程序(除非您真的希望它运行多次)

    【讨论】:

    • 天哪.. 这么简单的问题.. 很好!欣赏它!
    猜你喜欢
    • 2019-09-14
    • 1970-01-01
    • 1970-01-01
    • 2018-05-03
    • 1970-01-01
    • 2016-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多