C#.NET 3.5
我有一个控制台应用程序被另一个应用程序在计算机上调用。 这个控制台应用程序连续运行,并从“父”进程监听stdin上的数据。
但是,当父母停止或杀死,它启动的控制台应用程序继续。 在正常情况下,它使用最less的资源坐着等待来自stdin的input。 但是,一旦父母离开,这个控制台应用程序就会触发cpu,并以接近100%的利用率挨饿运行的核心。 这继续下去,直到我手动杀死进程。
理想情况下,主叫家长会自行清理,尤其是因为这是在正常(非常规)“停止”条件下发生的。 不幸的是,这个父母过程不在我的手中。
运行WPF程序时防止windows工作站(桌面)locking
如何安全地保存文件到磁盘没有windows拒绝的风险呢?
在本地运行Azure模拟器进行生产
限制在MS脚本引擎中使用名称空间
后台线程上的windows Mobile C#数据集更新
我的第一个想法是从控制台应用程序中获取调用的父级,并监视其PID。 如果父进程消失,我的控制台应用程序会自行终止。 目前,我正在做这个:
Process process = Process.GetCurrentProcess(); m_ParentPID = 0; using (ManagementObject mgmtObj = new ManagementObject("win32_process.handle='" + process.ID.ToString() + "'")) { mgmtObj.Get(); m_ParentPID = Convert.ToInt32(mgmtObj["ParentProcessID"]); } string parentProcessname = Process.GetProcessByID(m_ParentPID).Processname; Log("Parent Process: " + parentProcessname + Environment.Newline); // Create a timer for monitoring self. Timer timer = new Timer(new TimerCallback(sender => { if (m_ParentPID != 0) { Process parent = System.Diagnostics.Process.GetProcessByID(m_ParentPID); if (parent == null) { Log("Parent process stopped/killed. Terminating self."); System.Environment.Exit(0); } } })); // Kick on the timer timer.Change(m_ExitWatcherFrequency,m_ExitWatcherFrequency);
这只是部分工作,但它阻止了cpu的峰值,但是如果我从Sysinternals美妙的进程监视器看我的进程,我可以看到DW20.exe运行 – “微软应用程序错误报告”程序。 它只是…坐在那里,控制台应用程序仍然在内存中。
我应该在这里做些什么来正确地终止这个过程,以避免这个连续的cpu峰值和未释放的内存? 最终这需要在没有干预的情况下运行。
PS我在这里使用命令行应用程序作为“长时间运行的程序”而不是windows服务或Web服务,因为父程序只能configuration为执行命令行应用程序,通过stdin传递数据。 (对于那些好奇,这是ejabberd,使用外部authentication)。
编辑:
等待来自stdin的input的代码是:
// Read data from stdin char[] charray = new char[maxbuflen]; read = Console.In.Read(charray,2);
我之前提到,当父节点终止,控制台应用程序在cpu上疯狂。 我从Visual Studio中附加了一个deBUGging器,实际上它仍然在Console.In.Read中。 理论上,当自我监视计时器触发并且看到父母不在时,当另一个线程在该Read()行上时,它将尝试System.Environment.Exit(0)。
Dotnet核心应用程序在生产中找不到appsettings.Json
生成机器指纹的最佳方法是什么?
创build一个windows钩子来检测菜单点击
我可以使用没有.NET库的windows身份valIDation使用WCF REST服务吗?
在registry中创build子上下文菜单项
这听起来像你的进程正在进入一个硬回路,因为当父母退出时,控制台输入流被关闭。 你是否从Console.In.Read检查返回值? 当流关闭时它将返回零。 在这一点上打破了循环,让你的Main()方法本身退出。
而如果你正在运行多个线程,则必须先使用Thread.Join或等价的方法完成。
要监视进程退出,请使用Process类,并订阅Exited事件。
编辑:删除交互评论。
编辑(回复评论):
大多数情况下,在这种情况下完成的是将一些数据传回来,这样就可以在Console.In.Read方法调用中停止阻塞。
所以,当你发现父进程已经完成时,假设你设置了一个标志IsDone为true。 现在,因为你等待的过程不再发送任何东西,你仍然需要接收标准输入的东西,否则你将永远阻止。 所以,在你的事件处理程序/计时器代码中,写一些东西给你自己的进程的标准输入(如果你愿意的话,它甚至可以是一个特殊的值来表示你完成了)。 这会让你通过Console.In.Read方法。 一旦出来,检查是否设置了IsDone标志 – 如果是,停止处理并从主方法返回 – 不需要System.Environment.Exit 。
我会通过添加一个线程到您的控制台应用程序,基本上监视进程表中调用应用程序的存在来解决这个问题。 这是我的头顶,但这里有一些伪代码:
using System.Thread; using System.Diagnostics; main(){ Thread monitoringThread = new Thread(new ThreadStart(monitor)); monitoringThread.name = "Monitor"; monitoringThread.Start(); }
并在功能监视器中:
voID monitor(){ Process[] theCallers = Process.GetProcessesByname("CallingProcessname"); theCallers[0].WaitForExit(); Process.GetCurrentProcess().Kill(); }
假设在进程列表中只有一个调用进程,只要进程结束,这个也是一样。 你也可以为自己的进程提供更好的清理代码,而不是让它突然结束。
我喜欢mmr从孩子那里看父母的过程。 如果你有办法在命令行上传递父进程的PID,那就更好了。 从父进程内部,你可以得到PID:
System.Diagnostics.Process.GetCurrentProcess().ID
总结以上是内存溢出为你收集整理的什么是程序终止自己的进程的正确方法(Windows)全部内容,希望文章能够帮你解决什么是程序终止自己的进程的正确方法(Windows)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)