主线程结束后如何保持任务运行?

Posted

技术标签:

【中文标题】主线程结束后如何保持任务运行?【英文标题】:How to keep a task running after the main thread ends? 【发布时间】:2021-06-01 00:04:13 【问题描述】:

我有一个每 15 分钟运行一次的应用程序。我需要添加一个新任务(可能是一个方法),它将由应用程序调用并且应该异步运行,以便应用程序可以在 15 分钟内完成。如果新任务花费的时间比应用程序运行的时间长,它将被中止并且无法完成其工作。如何保持任务运行?

【问题讨论】:

在主线程等待它完成? 如果在下一次运行中之前的还没有完成会发生什么?它应该运行,它应该不运行还是应该等待上一次运行结束后再开始? 惯用的方式是C# 7.1引入的异步主要语言特性:c-sharpcorner.com/article/… @500-InternalServerError 这将限制主线程在 15 分钟内完成。 @Magnetron 它应该等待上一次运行结束,然后再开始新的运行。但是额外的任务不应该减慢主应用程序的速度。 【参考方案1】:

有几种方法可以解决这个问题。

独立进程

第一个是,不要运行任务,运行一个独立的进程来完成这项工作。第一个过程将在需要时结束;工作进程将在需要时结束,并且它们之间没有通信(除非出于其他原因需要)。

// in main thread...
var process = new Process(); // create the process
...
process.Start();
// process.WaitForExit(); this is commented out because you want main process to end without waiting
// main then ends here

现在上面的意思是创建两个单独的可执行文件;一个用于启动器,一个用于工作人员。这意味着两个独立的项目......或者不是。

您可以做的是在同一个可执行文件中拥有两组功能,并通过使用命令行参数分隔来调用您需要的功能。在你的主要你可以这样做:

static void Main(string[] args)

   if (args.Length == 1 && args[0] == "worker")
      DoWorkerStuff();
   else
   
      var process = new Process(); // create the process
      ...
      // use process API to call yourself with the arg
      process.Start();
      // process.WaitForExit(); this is commented out because you want main process to end without waiting
   

    // main then ends here for both the launcher and the worker

我喜欢这种方法,因为您由于进程边界而完全隔离,而且您不必编译和维护单独的项目。

等待主线程

第二种方式是让主线程等待,直到工作任务完成。试图让任务比主线程更有效可能会有问题。等待很容易

    // in main thread...
    var task = ... // however you create the task
    ...
    task.Wait(); // or one of the other Wait() overloads

当然,还有其他启动后台工作的方法(例如使用Thread)以及后台工作向主线程发出信号的方法,但这些都需要原始线程等待工作完成。

【讨论】:

自己的进程将是一个很好的解决方案。但是有没有办法不添加额外的.exe?就像我需要调用外部 .exe 文件一样吗?或者我可以从主进程中的方法执行代码吗?第二种解决方案将限制主进程完成:/ 谢谢,不,我理解这个概念 :) 但遗憾的是,我不知道如何实现这个 // 使用进程 API 用 arg 调用自己

以上是关于主线程结束后如何保持任务运行?的主要内容,如果未能解决你的问题,请参考以下文章

面试官:如何让主线程等待所有的子线程结束之后再执行?我懵了

java线程执行完后自己结束吗

如何使“主线程”等待“子线程”执行结束后再继续执行

如何使“主线程”等待“子线程”执行结束后再继续执行

delphi 多线程问题

如何使用 executor.execute 和 future.get() 结束任务(使线程超时)(通过上升中断)而不阻塞主线程