首页 > 解决方案 > 多线程 Windows 服务停止工作

问题描述

我正在使用 Windows 服务生成报告,比如大约 2K 报告。我也在使用 TPL 来提高性能。我观察到在本地机器上它对 40 报告工作正常,但在 2K 的 UAT 上它不能正常工作,它异常停止工作并启动 Windows 服务状态。系统事件查看器中没有事件日志条目(我假设我没有收到事件日志条目,因为服务状态已启动并且它没有异常终止)

这是我的代码块。

 foreach (pt_report report in reportCollection)
 {

    using(dbContent context=new dbContext())
    {
       //Execute 1 sp which takes around 2 minutes.
       //do some db operation to update status of sp execution.
      //This step is mandatory for all 2K plan before running Async task.

    }
    if(report.Status != Completed) //check for completion of report generation
    {
        Task generateReport = new Task(delegate
        {
           ScheduleMassReportGeneration(report); // This takes around 2-3 min more to generate pdf.
        });
        generateReport.Start();
        //Problem #1 occurs (see below description).
    }
 }

问题 1:

我知道当异步任务开始时,我需要写一些东西来连接线程,以便我可以检查执行状态。基于上面的代码,我无法控制它,现在就像孤儿一样。现在我想控制它,以便我可以检查该线程/任务发生了什么并将适当的状态记录到数据库并重新运行这些任务。

PS:在 method() 中编写了正确的日志记录,ScheduleMassReportGeneration()以跟踪生成报告时发生的情况。但我没有看到任何错误或可疑的迹象。它只是溜走了,没有留下任何痕迹。

标签: c#.netmultithreadingthread-safetytask-parallel-library

解决方案


答案是it depends......
通常当你想启动任务并控制它时,你可以使用

await Task.Run(() => ScheduleMassReportGeneration(report));

但在您的情况下,报告生成似乎是 CPU 密集型的,在这种情况下,将任务委派work给任务可能不会带来好处,因为在生成报告时没有什么可以做的。

如果报告是可以并行处理的,那么您可以为每个报告创建任务并最终等待所有报告完成:

var tasks = reportCollection.Where(r => r.Status != Completed)
    .Select(r => Task.Run(() => ScheduleMassReportGeneration(r)))
    .ToArray();

Task.WaitAll(tasks);

编辑1

服务快速启动和结束的原因是它完成了预期的一切。它只是创建任务然后完成。


推荐阅读