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. 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:
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):
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. 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.
You could use a System.Timers.Timer
that performs the check every x seconds:
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.
From the docs :
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
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.