是否应该使用Thread.Sleep()检查进程是否仍在运行?

时间:2019-05-23 09:26:03

标签: c# wpf multithreading sleep

正如标题所述,我目前正在制作WPF应用程序,我需要检测应用程序是否正在运行,并在关闭该应用程序时执行某些操作。我想这样做的方法是运行一个单独的线程,每两秒钟检查一次进程是否仍在运行,就像这样:

while(Process.GetProcessesByName(processName).Length != 0) {
    Thread.Sleep(2000);
}

//Do something

这将是一个好的解决方案,还有其他方法吗?

谢谢

3 个答案:

答案 0 :(得分:3)

  

这将是一个好的解决方案吗?

不,因为这将浪费整个线程几乎一无所有。

最好在WPF应用程序中最好使用计时器,最好是DispatcherTimer:

var timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(2) };

timer.Tick += (s, e) =>
{
    if (Process.GetProcessesByName(processName).Length > 0)
    {
        // ...
    }
};

timer.Start();

如果要在UI线程上执行冗长的操作,则可以使用等待Tick的异步Task事件处理程序(该事件处理程序将在后台的线程池线程上运行) ):

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();

答案 1 :(得分:1)

由于您已经在处理流程,我建议您直接使用它来确定它是否已经退出。您可以为代码使用Exited事件处理程序。因此,例如:

foreach (var process in Process.GetProcessesByName(processName))
{
  process.Exited += new EventHandler(DoSomething);
}

…

public void DoSomething(object sender, System.EventArgs e)
{
  // do something
}

当具有该名称的进程结束时,它将调用DoSomething

答案 2 :(得分:0)

您可以使用System.Timers.Timer每隔x秒执行一次检查:

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();
    }
}

Tick的{​​{1}}事件不同,DispatcherTimer的{​​{1}}事件始终在线程池线程中排队等待执行。

来自docs

  

如果在WPF应用程序中使用了Elapsed,则值得注意的是Timer在与用户界面(UI)线程不同的线程上运行...使用{{的原因1}}与System.Timers.Timer的不同之处在于System.Timers.TimerDispatcherTimer在同一线程上运行,并且可以在System.Timers.Timer上设置DispatcherTimer