我有一个小型C#控制台应用程序,它运行一些代码,然后检查要完成的特定可执行文件。
我遇到的问题(我通常不会编写控制台应用程序)就是当我找到检查可执行文件终止的代码时,我的Main()返回并且控制台应用程序关闭。检查可执行文件的代码是通过Timer()运行的。目前我通过添加while(true){}保持Main活着,这似乎正在起作用,除了它(显然)占用了大量的CPU时间。
是否有更好的方法可以阻止Main()函数返回?
static Timer tmrCheck = new Timer();
static void Main(string[] args)
{
Initialize();
while (true) ; // If this line is removed, the application will close after
// the last line of Initialize() is run.
}
static void Initialize()
{
tmrCheck.Elapsed += tmrCheck_Elapsed;
tmrCheck.Interval = 10000;
tmrCheck.Enabled = true; // After this line, Initialize returns to Main()
}
static void tmrCheck_Elapsed(object sender, ElapsedEventArgs e)
{
// Get a list of processes
// Check to see if process has exited
// If so, run *this* code then exit console application.
// If not, keep timer running.
}
答案 0 :(得分:1)
如果您只需要等到已启动的流程退出
这可以写在Timer.Elapsed
事件
Process[] p = Process.GetProcessesByName("yourprocessname");
if(p.Length > 0)
{
p[0].WaitForExit();
Console.WriteLine("Finish");
}
else
{
// Do other things
}
修改强>
看起来这可以尝试。我不确定这里的线程问题,所以等待更多的专家指出这种方法的弱点
static Timer tmrCheck = new Timer();
static bool waiting = false;
static void Main(string[] args)
{
Initialize();
Console.WriteLine("Press enter to stop the processing....");
Console.ReadLine();
tmrCheck.Stop();
}
static void Initialize()
{
tmrCheck.Elapsed += (s, e) =>
{
Console.WriteLine("Timer event");
if(!waiting)
{
Process[] p = Process.GetProcessesByName("yourprocessname");
if(p.Length > 0)
{
waiting = true;
Console.WriteLine("Waiting for exit");
p[0].WaitForExit();
Timer t = s as Timer;
t.Stop();
Console.WriteLine("Press enter to end application");
}
}
else
{
// other processing activities
}
};
tmrCheck.Interval = 10000;
tmrCheck.Enabled = true;
}
答案 1 :(得分:0)
尝试:Thread.Sleep(1);在你的while循环中。即使睡眠一毫秒也可以节省大量的CPU周期。
希望有所帮助
答案 2 :(得分:0)
你可以像其他人一样使用Thread.Sleep并像这样重写你的代码:
static void Main(string[] args)
{
while (true)
{
// Get a list of processes
// Check to see if process has exited
// If so, run *this* code then exit console application.
// If not, keep timer running.
Thread.Sleep(10000); // Wait 10s and retry your previous actions
}
}
另一个建议(我有时使用线程取消选项)
static void Main(string[] args)
{
int timeout = 10;
int timeoutCount = 10;
while (true)
{
//Here you can check cancellation flag
if(timeout == timeoutCount)
{
timeoutCount = 0;
// Get a list of processes
// Check to see if process has exited
// If so, run *this* code then exit console application.
// If not, keep timer running.
}
Thread.Sleep(1000); // Wait 1s and retry your previous actions
timeoutCount++;
}
}
答案 3 :(得分:0)
您可以尝试这样的事情:
static void Main(string[] args)
{
var procs = Process.GetProcessesByName("LINQPad").ToList();
if (procs.Any())
{
procs.ForEach(p => p.EnableRaisingEvents = true);
procs.ForEach(p => p.Exited += OnExited);
procs.ForEach(p => p.WaitForExit());
}
Console.WriteLine("All processes exited...");
Console.ReadKey();
}
private static void OnExited(object sender, EventArgs eventArgs)
{
Console.WriteLine("Process Has Exited");
}
您没有提及是否正在监控多个进程,但是您可以删除.ForEach语句并为单个进程执行相同的逻辑,如果没有。此外,我不确定Console.ReadKey()是否是您为防止进程退出而想到的...或者您是否只需要让它不会退出直到进程关闭。< / p>
答案 4 :(得分:0)
您没有说明您正在使用的.Net框架的版本,或者应用程序是否启动了该流程,但是......如果您使用的是4.0或更高版本并且该应用确实启动了该流程,那么您可以使用任务(System.Threading.Tasks)启动进程和Task.Wait。
using System.Threading.Tasks;
static Timer tmrCheck = new Timer();
Task doWork;
static void Main(string[] args)
{
Initialize();
/// do more work if required
doWork.Wait();
}
static void Initialize()
{
tmrCheck.Elapsed += tmrCheck_Elapsed;
tmrCheck.Interval = 10000;
tmrCheck.Enabled = true; // After this line, Initialize returns to Main()
// Initialize() seems the place to do start up, but this code could move to where ever the proocess is started.
doWork = Task.Factory.StartNew(() =>
{
startTheProcessHere();
}
);
}
Pluralsight有一个很好的课程:Introduction to Async and Parallel Programming in .NET 4