使用任务管理线程异常
本文关键字:异常 线程 任务管理 | 更新日期: 2023-09-27 18:15:11
我在主线程中创建一个任务,以便管理我的线程。我的目的是从AggregateException中获益,所以我希望任务在任务中启动的线程中出现异常时返回该异常,如下面的代码块所示。
public void ReportGeneratorFiveThreadTest()
{
var logger = new Log4NetLogger(typeof(ReportGeneratorThreadTest));
var tasks = new List<Task>();
for (var i = 0; i < 1; i++)
{
var estimatedReportSize = EstimatedReportSize.Normal;
var thread = new ReportGeneratorThread(logger, new ReportGenerator(20), estimatedReportSize);
var task = Task.Factory.StartNew(
() =>
{
thread.Start();
});
tasks.Add(task);
}
try
{
Task.WaitAll(tasks.ToArray());
Debug.WriteLine("Tasks are completed");
}
catch (AggregateException e)
{
foreach (var v in e.InnerExceptions)
{
Debug.WriteLine(e.Message + " " + v.Message);
}
}
}
GenerateReport()方法被启动的线程调用,它会抛出在该方法中定义的异常。
public void GenerateReport()
{
var didwork = false;
try
{
didwork = this.reportGenerator.GenerateReport(this.estimatedReportSize);
}
catch (Exception e)
{
this.log.LogError(ReportGenerator.CorrelationIdForPickingReport, string.Format(CultureInfo.InvariantCulture, "System"), string.Format(CultureInfo.InvariantCulture, "Error during report generation."), 0, e);
}
finally
{
if (!didwork)
{
Thread.Sleep(Settings.Default.ReportGenerationInterval);
}
}
}
问题是异常没有出现在任务中,因此,在这种情况下不会发生aggregateexception。是否有可能呈现这个发生在任务线程中的innerexception,从而触发aggregateexception ?
更新 ----------------------
我已经修改了我的代码如下:
public void Start()
{
this.running = true;
this.t = Task.Run(
() =>
{
this.GenerateReport();
});
try
{
Task.WaitAny(this.t);
}
catch (AggregateException e)
{
foreach (var v in e.InnerExceptions)
{
Debug.WriteLine(e.Message + " " + v.Message);
}
}
}
与:和
public void GenerateReport()
{
var didwork = false;
try
{
didwork = this.reportGenerator.GenerateReport(this.estimatedReportSize);
}
catch (Exception e)
{
this.log.LogError(ReportGenerator.CorrelationIdForPickingReport, string.Format(CultureInfo.InvariantCulture, "System"), string.Format(CultureInfo.InvariantCulture, "Error during report generation."), 0, e);
throw new InvalidOperationException("Failed");
}
finally
{
if (!didwork)
{
Thread.Sleep(Settings.Default.ReportGenerationInterval);
throw new InvalidOperationException("Failed");
}
}
}
,它仍然没有捕获AggregateException,即使在GenerateReport()方法中抛出InvalidOperationException。
首先,您必须在GenerateReport
方法的catch
块中重新抛出异常
public void GenerateReport()
{
var didwork = false;
try
{
...
}
catch (Exception e)
{
this.log.LogError(...);
throw; // Important!
}
finally
{
if (!didwork)
{
...
}
}
}
其次,你不应该在Task中使用Thread。只使用Tasks
public void ReportGeneratorFiveThreadTest()
{
var tasks = new List<Task>();
for (var i = 0; i < 1; i++)
{
var task = Task.Factory.StartNew(() =>
{
// No need thread here
GenerateReport();
});
tasks.Add(task);
}
try
{
...
}
catch (AggregateException e)
{
...
}
}