我有一个长时间运行的控制台应用程序(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/