当C#表格正在关闭时替代async / await,因为await永远不会返回?

时间:2015-06-18 23:06:52

标签: c# multithreading async-await task-parallel-library

我有一个C#Windows窗体应用程序,可以启动其他进程。当表单关闭时,我需要关闭这些进程并确保确定它们已经消失,以便它们不会像僵尸进程那样流连。我的策略是我通过套接字桥发送进程一个shutdown命令,并等待它们正常关闭。然而,在3秒后,如果他们还在,我强行关闭它们(杀死它们)。

最初我使用了生活在Form Closing 事件中的 await Task.Delay(3000)指令。然而,这并没有奏效。当 await Task.Delay(3000)语句试图返回时,主线程已经消失,因此该语句之后的代码强制关闭子进程,如果它们仍然在< strong> 从未执行过 。为了解决这个问题,我将 await Task.Delay(3000)改为普通的 Thread.Sleep(3000)语句。现在执行 Thread.Sleep(3000)之后的代码,因为线程永远不会像之前一样被切断。

但是,我的应用程序似乎没有响应的3秒钟。我可以使用什么技术来确保3秒等待后的代码肯定会执行,而不会阻塞主UI线程?

1 个答案:

答案 0 :(得分:-4)

在Form的Closing事件中,您可以启动一个新线程,它所做的只是:

  • 睡3秒
  • 然后杀死进程

因为睡眠发生在单独的线程上,所以您不必担心冻结UI。而且因为你的主题不是后台主题,它在睡觉时不会消失:)

修改

我运行这个简单的测试来证明我的观点。即使在我关闭表单并且FormClosing事件完成之后,我的线程仍在运行,并且应用程序仅在线程唤醒并完成其工作后才真正关闭。我疯了吗?

  private void Form1_FormClosing(object sender, FormClosingEventArgs e)
  {
     Thread t = new Thread(() =>
     {
        Thread.Sleep(10000);
        Debug.WriteLine("I am still alive!!!  So I can still kill the processes here");
        // After this point, the process shuts down, because this was the last thread running.
     });
     t.Start();

     // at this point, the form will close, but the process is still alive as long as thread `t` is alive.
  }

编辑2:

对于任何人都有这种冲动的冲动:至少拿一小段代码并在假设它不能工作之前尝试一下。如果它完全失败了,那就投降我,让我知道它,以便我可以从中学习。

但就目前而言,至少我做了我自己的一部分:我实际测试了这个,它确实有效。