我的项目有一个创建进程的对象。它是这个对象的Dispose函数,它会杀死进程(或尝试)。但是,如果程序崩溃,它将使进程继续运行并且不会清理。这导致程序下次失败,因为它试图再次启动进程并且无法锁定它。
如何确保此过程被杀死?我总是使用在using
块
供参考我正在使用C#和.NET 3.5
答案 0 :(得分:3)
定义“崩溃”;有不同级别的崩溃...例如,如果某些东西主动杀死你的进程,你将很少有机会运行任何Dispose / finalizers等 - 但是如果你的线程优雅地解开(即使是异常),你应该没问题(因为你正在使用using
)。你能澄清一下这个设置是什么吗?
答案 1 :(得分:1)
我知道这会让我大喊大叫,但是Enviroment.Exit()怎么样?这应该会杀死所有东西,每次=)尽管如此,做上述选择仍然会更好。
此外:
在Program.cs中,在调用Application.Run(Form)之前,请执行以下操作:
AppDomain.CurrentDomain.UnhandledException + = new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
然后放入一个类似这样的处理程序:
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
try
{
String CurrentThreadName = System.Threading.Thread.CurrentThread.Name;
if (e.IsTerminating)
Logger.Log("Program", 0, String.Format("Received fatal unhandled exception on '{0}' thread. Exception will follow.", CurrentThreadName), MsgCategory.Critical, 50);
else
Logger.Log("Program", 0, String.Format("Received unhandled exception on '{0}' thread. Exception will follow.", CurrentThreadName), MsgCategory.Error, 25);
if (e.ExceptionObject != null)
Logger.LogException("Program", String.Format("Unhandled System Exception on '{0}' thread.", CurrentThreadName), 50, (Exception)e.ExceptionObject);
}
catch
{
}
if (e.IsTerminating)
{
Exception ThisException = (Exception)e.ExceptionObject;
String CurrentThreadName = System.Threading.Thread.CurrentThread.Name;
MessageBox.Show(
String.Format(Localization.GetString("fatal_error"), ThisException.GetType().ToString(), ThisException.Message, ThisException.StackTrace, CurrentThreadName)
, Localization.GetString("dialogtitle")
, MessageBoxButtons.OK
, MessageBoxIcon.Error
, MessageBoxDefaultButton.Button1);
}
}
答案 2 :(得分:1)
如果要确保子进程终止,请考虑创建一个单独且更简单的监视程序进程,查看任何一个进程终止的进程空间。通常更容易使其防弹。无法保证在所有情况下执行清理代码。
但是,您并没有真正提供有关如何创建子进程的足够上下文,以允许任何有关如何设计监视程序以了解父进程和子进程的相关建议。
答案 3 :(得分:0)
正在推出什么类型的计划?即使第一个实例仍在运行,也应该可以启动第二个实例 - 启动进程不会锁定任何内容(除非程序本身做了一些奇怪的事情)。
对象如何启动该过程?如果它有句柄,它应该能够通过调用TerminateProcess API立即终止它。
如果调用者死亡,确保生成的进程将会死亡的问题是一个真正的hacky解决方案:调用DebugActiveProcess,传递子进程ID。
答案 4 :(得分:0)
Foo bar = new Foo();
try
{
bar.DoSomething();
}
catch // if required
{
}
finally
{
if(bar != null)
{
bar.Dispose(); // code from finally clause is ~always executed
}
}
等于
using(Foo bar = new Foo())
{
// ..
}
答案 5 :(得分:0)
您真正想要的是双向流程监控,以便在父流程或子流程死亡时,您可以采取适当的措施。最简单的方法是让它们在一个计时器上相互ping通(每30秒,例如,你必须调整你的需要),如果你发送下一个ping时没有响应,那么你可以假设另一个进程已经死亡,被锁定或以其他方式停止玩得很好。
如果父母停止响应,孩子应该退出。如果孩子停止响应,请将其杀死并重新开始。
如何实现ping可以作为读者的练习,但任何IPC机制都可以 - 窗口消息,RPC调用,管道......无论你喜欢什么。把事情简单化;我确定.net有你可以使用的东西。