主线程结束后如何保持任务运行?
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 调用自己以上是关于主线程结束后如何保持任务运行?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 executor.execute 和 future.get() 结束任务(使线程超时)(通过上升中断)而不阻塞主线程