繁体   English   中英

使用TPL Task杀死.net控制台应用程序

[英]Kill .net Console application from with TPL Task

我有一个长期运行的控制台应用程序(3小时),我需要在某些情况下使用异常终止。 杀死此批次的原因是它由运营商监控并由企业调度程序控制。 未处理的异常将提醒他们及其在呼叫支持中使用的消息。

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

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操作中修改全局属性,并从主线程中查询此属性,抛出异常。

我已经对网络有了很好的了解,虽然有很多从主要取消线程,但没有什么可以从后台线程中杀死主线程。

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

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

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

Environment.Exit()可能是最简单的方法。 例如,以下程序将在打印约10个数字后退出,而不是完整的100个。

public static void Main(string[] args)
{
    Task.Run(() =>
    {
        Thread.Sleep(1000);
        Console.Out.WriteLine("Something has gone terribly wrong!");
        System.Environment.Exit(1);
    });

    for (int i = 0; i < 100; i++)
    {
        Console.Out.WriteLine(i);
        Thread.Sleep(100);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM