我正在使用一个开发不好的应用程序,由于内存泄漏或其他随机错误(如果重新启动时不重复)而不断重启。我无法访问代码,无法解决问题。
我已经开发了ac#app来管理重启并在程序停止时保持程序运行,但是如何识别挂起(或者当它崩溃但是Windows错误消息使其“运行”)。
我可以使用System.Diagnostics
来检测60秒内CPU时间增量是否为0(因为该过程通常为25-30秒,CPU使用率约为50%),但这会导致进程中不必要的重启资源闲置(因为它有一个查询密集型步骤,可以持续10分钟到2小时)。
那么如何检测程序是否在等待mssql查询或网络资源,和/或如何检测和实现这样的内容:http://msdn.microsoft.com/en-us/library/aa373347.aspx?
这是我使用的简化示例:
//every 60 seconds
Process[] procs;
procs = Process.GetProcessesByName(appName);
List<int> pidsRunning = new List<int>();
foreach(Process p in procs){
pidsRunning.add(p.id);
//other gathering of data and command line arguments
}
foreach(int pid in pidsLast){
if(!pidsRunning.Contains(pid)){
//do stuff if not running
}
}
pidsRunning = pidsLast;
我尝试使用p.responding
,但在我的情况下,即使应用程序发生了错误,也设置为 true :
Program has stopped responding
details:
Problem signature:
Problem Event Name: APPCRASH
Application Name: app.exe
Application Version: 1.0.0.0
Application Timestamp: 500efec6
Fault Module Name: mshtml.dll
Fault Module Version: 8.0.7600.17267
Fault Module Timestamp: 5131882e
Exception Code: c0000005
Exception Offset: 00429796
OS Version: 6.1.7600.2.0.0.274.10
Locale ID: 1033
Additional Information 1: 0a9e
Additional Information 2: 0a9e372d3b4ad19135b953a78882e789
Additional Information 3: 0a9e
Additional Information 4: 0a9e372d3b4ad19135b953a78882e789
这是同一程序的过程对象:
- p {System.Diagnostics.Process (app)} System.Diagnostics.Process
- base {System.Diagnostics.Process (app)} System.ComponentModel.Component {System.Diagnostics.Process}
+ base {System.Diagnostics.Process (app)} System.MarshalByRefObject {System.Diagnostics.Process}
Container null System.ComponentModel.IContainer
Site null System.ComponentModel.ISite
+ Static members
+ Non-Public members
BasePriority 8 int
EnableRaisingEvents false bool
+ ExitCode 'p.ExitCode' threw an exception of type 'System.InvalidOperationException' int {System.InvalidOperationException}
+ ExitTime 'p.ExitTime' threw an exception of type 'System.InvalidOperationException' System.DateTime {System.InvalidOperationException}
+ Handle 2368 System.IntPtr
HandleCount 614 int
HasExited false bool
Id 4148 int
MachineName "." string
+ MainModule {System.Diagnostics.ProcessModule (app.exe)} System.Diagnostics.ProcessModule
+ MainWindowHandle 1771888 System.IntPtr
MainWindowTitle "C:\\app.exe" string
+ MaxWorkingSet 1413120 System.IntPtr
+ MinWorkingSet 204800 System.IntPtr
+ Modules {System.Diagnostics.ProcessModuleCollection} System.Diagnostics.ProcessModuleCollection
NonpagedSystemMemorySize 59684 int
NonpagedSystemMemorySize64 59684 long
PagedMemorySize 63553536 int
PagedMemorySize64 63553536 long
PagedSystemMemorySize 490456 int
PagedSystemMemorySize64 490456 long
PeakPagedMemorySize 69619712 int
PeakPagedMemorySize64 69619712 long
PeakVirtualMemorySize 386330624 int
PeakVirtualMemorySize64 386330624 long
PeakWorkingSet 91586560 int
PeakWorkingSet64 91586560 long
PriorityBoostEnabled true bool
PriorityClass Normal System.Diagnostics.ProcessPriorityClass
PrivateMemorySize 63553536 int
PrivateMemorySize64 63553536 long
+ PrivilegedProcessorTime {00:00:20.7793332} System.TimeSpan
ProcessName "app" string
+ ProcessorAffinity 255 System.IntPtr
Responding true bool
SessionId 2 int
+ StandardError 'p.StandardError' threw an exception of type 'System.InvalidOperationException' System.IO.StreamReader {System.InvalidOperationException}
+ StandardInput 'p.StandardInput' threw an exception of type 'System.InvalidOperationException' System.IO.StreamWriter {System.InvalidOperationException}
+ StandardOutput 'p.StandardOutput' threw an exception of type 'System.InvalidOperationException' System.IO.StreamReader {System.InvalidOperationException}
+ StartInfo {System.Diagnostics.ProcessStartInfo} System.Diagnostics.ProcessStartInfo
+ StartTime {10/5/2013 2:19:53 PM} System.DateTime
SynchronizingObject null System.ComponentModel.ISynchronizeInvoke
+ Threads {System.Diagnostics.ProcessThreadCollection} System.Diagnostics.ProcessThreadCollection
+ TotalProcessorTime {00:07:39.5633459} System.TimeSpan
+ UserProcessorTime {00:07:18.7840127} System.TimeSpan
VirtualMemorySize 378003456 int
VirtualMemorySize64 378003456 long
WorkingSet 88723456 int
WorkingSet64 88723456 long
+ Static members
- Non-Public members
+ base {System.Diagnostics.Process (app)} System.ComponentModel.Component {System.Diagnostics.Process}
Associated true bool
disposed false bool
error null System.Diagnostics.AsyncStreamReader
ErrorDataReceived null System.Diagnostics.DataReceivedEventHandler
errorStreamReadMode undefined System.Diagnostics.Process.StreamReadMode
exitCode 259 int
exited false bool
+ exitTime {1/1/0001 12:00:00 AM} System.DateTime
haveExitTime false bool
haveMainWindow true bool
havePriorityBoostEnabled true bool
havePriorityClass true bool
haveProcessHandle true bool
haveProcessId true bool
haveProcessorAffinity true bool
haveResponding false bool
haveWorkingSetLimits true bool
isRemoteMachine false bool
m_processAccess 2035711 int
+ m_processHandle {Microsoft.Win32.SafeHandles.SafeProcessHandle} Microsoft.Win32.SafeHandles.SafeProcessHandle
machineName "." string
mainWindowHandle 1771888 System.IntPtr
mainWindowTitle "C:\\app.exe" string
maxWorkingSet 1413120 System.IntPtr
minWorkingSet 204800 System.IntPtr
+ modules {System.Diagnostics.ProcessModuleCollection} System.Diagnostics.ProcessModuleCollection
onExited null System.EventHandler
+ OperatingSystem {Microsoft Windows NT 6.1.7600.0} System.OperatingSystem
+ operatingSystem {Microsoft Windows NT 6.1.7600.0} System.OperatingSystem
output null System.Diagnostics.AsyncStreamReader
OutputDataReceived null System.Diagnostics.DataReceivedEventHandler
outputStreamReadMode undefined System.Diagnostics.Process.StreamReadMode
pendingErrorRead false bool
pendingOutputRead false bool
priorityBoostEnabled true bool
priorityClass Normal System.Diagnostics.ProcessPriorityClass
processId 4148 int
processInfo {System.Diagnostics.ProcessInfo} System.Diagnostics.ProcessInfo
processorAffinity 255 System.IntPtr
raisedOnExited false bool
registeredWaitHandle null System.Threading.RegisteredWaitHandle
responding true bool
signaled false bool
standardError null System.IO.StreamReader
standardInput null System.IO.StreamWriter
standardOutput null System.IO.StreamReader
- startInfo {System.Diagnostics.ProcessStartInfo} System.Diagnostics.ProcessStartInfo
Arguments "" string
CreateNoWindow false bool
Domain "" string
+ EnvironmentVariables {System.Collections.Specialized.StringDictionaryWithComparer} System.Collections.Specialized.StringDictionary {System.Collections.Specialized.StringDictionaryWithComparer}
ErrorDialog false bool
+ ErrorDialogParentHandle 0 System.IntPtr
FileName "" string
LoadUserProfile false bool
+ Password null System.Security.SecureString
RedirectStandardError false bool
RedirectStandardInput false bool
RedirectStandardOutput false bool
+ StandardErrorEncoding null System.Text.Encoding
+ StandardOutputEncoding null System.Text.Encoding
UserName "" string
UseShellExecute true bool
Verb "" string
Verbs {string[0]} string[]
WindowStyle Normal System.Diagnostics.ProcessWindowStyle
WorkingDirectory "" string
+ Non-Public members
synchronizingObject null System.ComponentModel.ISynchronizeInvoke
- threads {System.Diagnostics.ProcessThreadCollection} System.Diagnostics.ProcessThreadCollection
- base {System.Diagnostics.ProcessThreadCollection} System.Collections.ReadOnlyCollectionBase {System.Diagnostics.ProcessThreadCollection}
Count 36 int
- Non-Public members
+ [System.Diagnostics.ProcessThreadCollection] {System.Diagnostics.ProcessThreadCollection} System.Diagnostics.ProcessThreadCollection
+ InnerList Count = 36 System.Collections.ArrayList
+ list Count = 36 System.Collections.ArrayList
System.Collections.ICollection.IsSynchronized false bool
System.Collections.ICollection.SyncRoot {object} object
waitHandle null System.Threading.WaitHandle
watchForExit false bool
watchingForExit false bool
答案 0 :(得分:2)
Process[] procs;
procs = Process.GetProcessesByName(appName);
bool restartRequired = false;
foreach (Process proc in procs) {
if (!proc.Responding) {
restartRequired = true;
proc.Kill();
break;
}
}
if (restartRequired) {
Process procRun = new Process();
procRun.StartInfo.FileName = @"C:\Program Files\Winword.exe"
procRun.Start();
}
答案 1 :(得分:0)
您可以通过多种方式试验自己的应用。试试以下两个,
System.Reflection.Assembly app = System.Reflection.Assembly.LoadFrom("c:\\Windows\\ConsoleApp.exe");
Type[] types = app.GetTypes();
foreach (Type type in types)
{
System.Reflection.MethodInfo method = type.GetMethod("Main", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
if (method != null)
{
tryAgain:
try
{
method.Invoke(null, null);
}
catch (Exception ex)
{
System.Threading.Thread.Sleep(2000); // Wait for 2 seconds if u wish..
goto tryAgain;
}
break;
}
}
和
void init()
{
loadProcess();
}
void loadProcess()
{
System.Threading.Thread.Sleep(2000);
System.Diagnostics.Process prc = new System.Diagnostics.Process();
prc.StartInfo.FileName = "C:\\Windows\\ConsoleApp.exe";
prc.Exited += new EventHandler(prc_Exited); // Event Handler when the process is exited. (Mostly not working 4 me)
prc.Start();
}
void prc_Exited(object sender, EventArgs e)
{
loadProcess();
}
答案 2 :(得分:0)
由于您遇到的实际案例是由未处理的异常引起的APPCRASH,您可以将自定义应用程序设置为JIT调试器,请参阅此处:
http://msdn.microsoft.com/en-us/library/vstudio/5hs4b7a6.aspx
您的自定义/替换JIT调试器将检查崩溃的应用程序是否是您正在观看的应用程序,如果是,则重新启动它,如果没有则传递给真正的JIT调试器。