【问题标题】:Kill .net Console application from with TPL Task使用 TPL 任务杀死 .net 控制台应用程序
【发布时间】:2015-03-24 17:38:56
【问题描述】:

我有一个长时间运行的控制台应用程序(3 小时),在某些情况下我需要用异常杀死它。杀死这个批次的原因是它由操作员监控并由企业调度程序控制。未处理的异常会提醒他们,并通知待命支持人员使用的消息。

理想情况下,我希望后台线程作为 TPL 任务运行以检查这些数据库定义的标准,如果遇到则抛出异常以使进程失败。在任务中抛出异常不会杀死主线程。我尝试了以下方法,在 main 的调度程序上运行 ContinueWith 任务,但它不影响 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 操作中修改全局属性,并从主线程中查询该属性,引发异常。

我浏览了整个网络,虽然有很多关于从主线程中取消线程的内容,但没有关于从后台线程中杀死主线程的内容。

【问题讨论】:

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


    【解决方案1】:

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

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

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

    【讨论】:

    • 我以前没有听说过FailFast。文档暗示它可能不会运行 try/finally 块或终结器,这可能是一个问题,具体取决于程序设计。
    • @BrianReischl 正如我在 cmets 中所说,等待 CT 是一种更强大的设计 IMO,但 FailFast 是对 OP 问题的直接回答。
    • @i3arnon 感谢您的回复。我不确定是否使用全局令牌,因为据我了解,它需要主线程频繁轮询,我想避免这种情况。
    • @ms10 我不是这个意思。 CT 不需要任何轮询。
    【解决方案2】:

    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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-04-10
      • 1970-01-01
      • 1970-01-01
      • 2011-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多