[英]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.