c# - 使用 TPL 任务杀死 .net 控制台应用程序

标签 c# .net multithreading task-parallel-library task

我有一个长时间运行的控制台应用程序(3 小时),在某些情况下我需要用异常终止它。杀死这个批处理的原因是它由运算符(operator)监视并由企业调度程序控制。未处理的异常会提醒他们,并且它的消息会被随叫随到的支持人员使用。

理想情况下,我希望后台线程作为 TPL 任务运行以检查这些数据库定义的条件,如果遇到则抛出异常以使进程失败。在 Task 中抛出异常不会杀死主线程。我尝试了以下操作,在主程序的调度程序上运行 ContinueWith 任务,但它不会影响主程序。

static void Main(string[] args)
{
    var mainThread = TaskScheduler.Current;
    var taskDb = new Task<bool>(RunDb, TaskCreationOptions.LongRunning);
    var taskHandle = taskDb.ContinueWith(b => Check(b.Result), mainThread);
    taskDb.Start();

    //do stuff
}

static bool RunDb()
{
    //check database in loop
    //if validation failed return false

    return false;
}

static void Check(bool successful)
{
    //check database in loop
    //if validation failed return false

    if(!successful)
       throw new Exception("batch failed for these reasons...");   
}

我找到的唯一可能的解决方案是从 ContinueWith 操作中修改全局属性,并从主线程中查询该属性,抛出异常。

我仔细查看了网络,虽然有很多关于从 main 中取消线程的内容,但没有关于从后台线程中杀死 main 的内容。

最佳答案

您可以在任何地方使用 Environment.FailFast 来关闭您的应用程序并出现异常。这也适用于后台线程:

Task.Run(() => Environment.FailFast("Fail", new Exception("batch failed for these reasons...")));

但是,我认为更稳健的设计是拥有一个系统范围的 CancellationToken,您可以从您的任务中取消它,从而优雅地关闭整个应用程序。

关于c# - 使用 TPL 任务杀死 .net 控制台应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29239347/

相关文章:

java - 从线程的内部线程启动 android Activity 。

c# - 泛型类中有歧义/冲突的构造函数

c# - .NET 中泛型参数的数量限制?

asp.net - 在开发人员之间共享加密的 web.config

PowerShell 5 中从未处理过的 C# 事件

.net - 如何将描述性文本解析为 DateTime 对象?

sql-server - VB.Net(或 C#)2008 多线程导入

javascript - 未初始化的变量内存分配

c# - 如何将列表参数添加到 LINQ 查询?

java - 每个 tomcat 创建一个实例