【问题标题】:Monitoring multiple processes with same name监控多个同名进程
【发布时间】:2018-05-04 07:09:19
【问题描述】:

我正在做一个项目,我使用 Process 类启动了 4 个进程,它们具有相同的名称。

我尝试使用Process.HasExited,但因为它是同名的进程,我无法真正获得一个已关闭的进程。

我也尝试过使用 ID,因为它们确实有不同的 ID,但它并没有像我想象的那样工作,例如当我关闭第二个进程窗口然后检查缺少哪个 ID 时,他不会返回缺少第二个 ID,它总是随机的

我也在使用 WCF 连接,并且我有 CheckState 方法,我的所有代理每五秒调用一次,所以当进程数少于 4 时,它会返回错误并且我知道有一个进程已退出。

这就是我启动进程的方式

        for (int i = 0; i < 4; ++i)
        {
            try
            {
                Process.Start(path, Containers.Path.ports[i]);
                NetTcpBinding binding = new NetTcpBinding();
                ChannelFactory<IContainer> factory = new ChannelFactory<IContainer>(binding, new EndpointAddress($"net.tcp://localhost:{Containers.Path.ports[i]}/IContainer")); 
                proxies.Add(factory.CreateChannel());
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);

            }
        }

这就是我检查哪个进程已停止并返回 0-3 的数字的方式,因为我已经预定义了可以使用的“端口”,所以基本上我只需要确定退出进程的数量

private static int GetID(Dictionary<int, int> processesIDs, Process[] newProcessList)
    {
        int cnt=0;
        int ret = -1;

        foreach (var p in processesIDs)
        {
            if(cnt == newProcessList.Length)
            {
                ret = p.Value;
                break;
            }else
            {
                cnt = 0;
                for (int i = 0; i < newProcessList.Length; ++i)
                {
                    if (p.Key != newProcessList[i].Id)
                    {
                        cnt++;
                    }
                }
            }

        }

        if(ret == -1)
        {
            ret = 4;
        }else
        {
            ret = ret - 1;
        }

        return ret;
    }

我的假设是他不会像我在控制台运行时看到的那样排列进程,这意味着当我关闭第二个应用程序窗口时,我希望第二个进程完成。

【问题讨论】:

  • 请添加代码示例:如何创建进程以及如何检查它们是否仍然存在。进程ID是唯一的,所以在这样的任务中使用它是正确的,但是没有代码很难判断你做错了什么。
  • @IgorLabutin 我编辑了帖子,希望对您有所帮助
  • Process.Start() 返回一个Process - 你能用它们来代替吗?还是我没有抓住重点?
  • @C.Evenhuis 只是为了解释一下,在这本词典中,我将进程 ID 存储为键,将 0 到 3 的数字存储为值,所以基本上我确实使用了这些进程,只是没有将它们存储在一开始,我使用了Process.GetProcessesByName函数。
  • @Serlok 但是当您保留 Process 实例时,您可以检查它们的 HasExited 属性,对吗?可能值得一试。

标签: c# wcf process


【解决方案1】:

正如 Evenhuis 所说,我在开始时存储了进程,当我创建它们时,然后我存储在 public static Dictionary&lt;Process, string&gt; 中。

以后想查看哪个退出了,就用这个方法

public static string GetPort(Dictionary<Process, string> OriginalprocessesIDs)
    {
        string ret = "";
        foreach(var p in processesIDs)
        {
            if(p.Key.HasExited)
            {
                ret = p.Value;
                OriginalprocessesIDs.Remove(p.Key);
                return ret;
            }
        }

        return ret;
    }

因为hasExited 属性在此过程中保持为真,我需要将其从 dict 中删除。当我想启动新进程时,我需要创建新的ChannelFactory 并将其保存为新进程。

public static void StartSingleProcess(string port)
    {
        Process p = Process.Start(Containers.Path.location, port);
        NetTcpBinding binding = new NetTcpBinding();
        binding.OpenTimeout = new TimeSpan(0, 10, 0);
        binding.CloseTimeout = new TimeSpan(0, 10, 0);
        binding.SendTimeout = new TimeSpan(0, 10, 0);
        binding.ReceiveTimeout = new TimeSpan(0, 10, 0);
        ChannelFactory<IContainer> factory = new ChannelFactory<IContainer>(binding, new EndpointAddress($"net.tcp://localhost:{port}/IContainer")); // moraju se cuvati proxiji zbog poziva metode load n puta 
        proxies.Add(factory.CreateChannel());
        OriginalprocessesIDs.Add(p, port);
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多