c# - 正在运行任务的关闭表单

标签 c# winforms task task-parallel-library

我有一个 WinForms 应用程序,它包含一个主 UI 线程和 4 个任务。我的主窗体有一个私有(private)成员级别变量,如下所示:

private bool keepThreadsRunning = false;

在我的主窗体的 Load() 事件中,我有以下内容:

keepThreadsRunning = true;
var task1Worker = Task.Factory.StartNew(() => DoStuff1());
var task2Worker = Task.Factory.StartNew(() => DoStuff2());
var task3Worker = Task.Factory.StartNew(() => DoStuff3());
var task4Worker = Task.Factory.StartNew(() => DoStuff4());

在我的每个 DoStuff() 方法中,我基本上都有这个:

while (keepThreadsRunning)
{
  // do work here
  Thread.Sleep(30000); // a couple of my tasks only need to run every 30 seconds or so
}

最后,在我的 Form_Closing() 事件处理程序中,我有以下内容:

keepThreadsRunning = false;
this.Close();

在任务管理器中查看我的应用程序,当我关闭表单时,进程似乎正在结束,但我对这四个任务有点困惑。我对 this.Close() 的调用是否真的导致这些任务终止(即使它们在 Thread.Sleep() 调用中发生)?有没有比我现在编码的方式更好的方法来实现这一目标?

编辑 - 我已经简要了解了任务取消(当我的应用程序退出时),但我的理解是我的任务需要定期检查取消 token 以确定它们是否已被取消。考虑到我的一些任务需要每 30 秒运行一次,我无法弄清楚如何实现 30 秒的等待(当前是 Thread.Sleep())并且仍然让任务检查取消 token 。

最佳答案

与其使用 bool 值和 Thread.Sleep(),不如使用 WaitHandle ,特别是 ManualResetEvent , 像这样创建:

var threadTerminationHandle = new ManualResetEvent(false);

在您的主题中:

do {
  // do work here
} while (!threadTerminationHandle.WaitOne(TimeSpan.FromSeconds(30))

这将等到设置 WaitHandle 或 30 秒后,以较早者为准。

在你的表单中:

threadTerminationHandle.Set();
Close();

关于c# - 正在运行任务的关闭表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12532281/

相关文章:

c# - 如何在按住鼠标的情况下移动表单?

maven-2 - 使用Maven执行Ant任务

c# - c# 中的这个 foreach 是怎么回事?

c# - 开发人员是否可以通过 "force"系统来防止 "Metro"应用程序在后台异步进程运行时被挂起?

c# - Azure 数据湖与数据工厂自定义事件的连接

javafx-2 - javafx 后台任务未运行多次

f# - 我什么时候应该使用 Async.AwaitIAsyncResult 而不是 Async.AwaitTask 来等待任务?

c# - 通用方法调用重复

c# - 如何在至少打开一个模式窗口时最小化 winforms 应用程序

c# - Seemann 依赖注入(inject), "Three Calls Pattern"与服务定位器反模式