这是我的代码。运行时间会增加内存使用量,直到由于此错误而停止:
由于StackOverFlowException
,进程终止
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace KillWW
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Starting... {0} ", DateTime.Now);
killWinword();
// Console.Read();
}
private static void killWinword()
{
var procs = Process.GetProcesses();
foreach (var proc in procs)
{
if (proc.ProcessName == "WINWORD")
{
TimeSpan runtime;
runtime = DateTime.Now - proc.StartTime;
if (DateTime.Now > proc.StartTime.AddSeconds(20))
{
proc.Kill();
}
}
}
Thread.Sleep(1000);
killWinword();
}
}
}
有人能解释一下它的原因是什么吗?请帮我。感谢。
答案 0 :(得分:3)
KillWinWord的最后一行正在调用自己。所以每秒(在睡眠之后)你在堆栈上添加一个新层。
如果您希望kill功能永久持续,请使用while循环替换递归调用。
答案 1 :(得分:0)
您有一个没有停止条件的递归调用。 (killWinword
调用killWinword
,调用killWinword
...)
所以它是一个无限递归。每个新调用都会占用更多的空间。这迟早会在Stackoverflow中结束。
似乎你想每秒都做一次检查。你可以:
(没有具体的订单。我个人会去异步/等待,但其他解决方案也适用于这个简单的短程序。)
计时器的警告是你必须检查最后一次调用是否仍在运行。 Task的优点是您可以轻松使用Threadpool。
示例:
// Run-Flag to gracefully exit loop.
private static volatile bool _keepRunning = true;
private static ManualResetEvent _exitRequest = new ManualResetEvent(false);
static void Main(string[] args)
{
Console.WriteLine("Starting... {0} ", DateTime.Now);
Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e) {
e.Cancel = true;
MainClass._keepRunning = false;
};
Task.Run(() => KillWinword); // Start Task on ThreadPool
//You don't want to use Console.Read(); So ... wait for Ctrl-C?
_exitRequest.WaitOne();
}
private static async Task KillWinword()
{
try
{
// Loop instead of recursion
while(_keepRunning)
{
// Do your checks here
DoKillWinword();
// Don't delay if exit is requested.
if(_keepRunning) await Task.Delay(1000);
}
}
finally
{
_exitRequest.Set();
}
}
private static void DoKillWinword()
{
// TIPP: You should add some Exception handling in here!
var procs = Process.GetProcesses();
foreach (var proc in procs)
{
if (proc.ProcessName == "WINWORD")
{
TimeSpan runtime;
runtime = DateTime.Now - proc.StartTime;
if (DateTime.Now > proc.StartTime.AddSeconds(20))
{
proc.Kill();
}
}
}
}
请注意,这不会每秒都开始检查。它将在前一个完成后1秒开始新的检查。