[英]Should I use Thread.Sleep() to check if a process is still running?
As title says, I'm currently making a WPF application and I need to detect if an application is running and do something when it's closed. 如标题所述,我目前正在制作WPF应用程序,我需要检测应用程序是否正在运行并在关闭时执行某些操作。 The way I'd thought of doing so is by running a separate Thread and checking every two seconds if the process is still running, something like this: 我想到的方法是运行一个单独的线程,每两秒钟检查一次进程是否仍在运行,如下所示:
while(Process.GetProcessesByName(processName).Length != 0) {
Thread.Sleep(2000);
}
//Do something
Would this be a good solution, is there any other way of doing this? 这将是一个好的解决方案,还有其他方法吗?
Thanks 谢谢
Would this be a good solution? 这将是一个好的解决方案吗?
No, because it would waste an entire thread for nearly nothing. 不,因为这几乎浪费了整个线程。
Better use a timer, in a WPF application preferrably a DispatcherTimer: 最好在WPF应用程序中最好使用计时器,最好是DispatcherTimer:
var timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(2) };
timer.Tick += (s, e) =>
{
if (Process.GetProcessesByName(processName).Length > 0)
{
// ...
}
};
timer.Start();
If there would be a lengthy operation to be performed off the UI thread, you could use an async Tick
event handler that awaits a Task
(which would run on a thread pool thread in the background): 如果要在UI线程上执行冗长的操作,则可以使用等待Task
的异步Tick
事件处理程序(它将在后台在线程池线程上运行):
var timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(2) };
timer.Tick += async (s, e) =>
{
if (Process.GetProcessesByName(processName).Length > 0)
{
await Task.Run(() =>
{
// lengthy operation here which runs on a thread pool thread
});
// udate UI here
}
};
timer.Start();
Since you are already dealing with Processes, I would suggest just using it directly to determine if it has exited. 由于您已经在处理流程,因此建议您直接使用它来确定它是否已退出。 You can use the Exited event handler for your code. 您可以为代码使用Exited事件处理程序。 So, for instance: 因此,例如:
foreach (var process in Process.GetProcessesByName(processName))
{
process.Exited += new EventHandler(DoSomething);
}
…
public void DoSomething(object sender, System.EventArgs e)
{
// do something
}
This will call DoSomething
when the process with that name ends. 当具有该名称的进程结束时,这将调用DoSomething
。
You could use a System.Timers.Timer
that performs the check every x seconds: 您可以使用每隔x秒执行一次检查的System.Timers.Timer
:
public sealed partial class Window1 : Window, IDisposable
{
private readonly System.Timers.Timer _timer = new System.Timers.Timer(TimeSpan.FromSeconds(2).TotalMilliseconds);
public Window1()
{
InitializeComponent();
_timer.Elapsed += _timer_Elapsed;
_timer.Start();
}
private void _timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (Process.GetProcessesByName("processName...").Length == 0)
{
_timer.Stop();
_timer.Dispose();
//do something...
}
}
public void Dispose()
{
_timer.Dispose();
}
}
Unlike the Tick
event of a DispatcherTimer
, the Elapsed
event of a Timer
is always queued for execution on a thread pool thread. 与DispatcherTimer
的Tick
事件不同, Timer
的Elapsed
事件始终在线程池线程中排队等待执行。
If a
System.Timers.Timer
is used in a WPF application, it is worth noting that theSystem.Timers.Timer
runs on a different thread than the user interface (UI) thread...Reasons for using aDispatcherTimer
as opposed to aSystem.Timers.Timer
are that theDispatcherTimer
runs on the same thread as theDispatcher
and aDispatcherPriority
can be set on theDispatcherTimer
. 如果在WPF应用程序中使用System.Timers.Timer
,则值得注意的是System.Timers.Timer
在与用户界面(UI)线程不同的线程上运行...使用DispatcherTimer
原因,而不是System.Timers.Timer
是该DispatcherTimer
运行同一个线程中的Dispatcher
和DispatcherPriority
可以在设置DispatcherTimer
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.