【发布时间】:2015-12-28 04:31:00
【问题描述】:
我正在我的主线程中创建一个任务来管理我的线程。我的目的是从 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);
}
}
}
问题是任务中没有出现异常,因此在这种情况下不会发生聚合异常。是否可以呈现这个innerexception,它发生在任务中的线程中,因此触发了聚合异常?
更新----------
我修改了以下代码:
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");
}
}
}
即使在 GenerateReport() 方法中抛出了 InvalidOperationException,它仍然没有捕获 AggregateException。
【问题讨论】:
-
捕获并记录后抛出异常。即 GenerateReport 需要实际抛出。或者,GenerateReport 实际上可以返回一些东西(即 null 或异常),您可以拥有 Task
并遍历返回值。 -
这也无济于事。似乎主线程在线程抛出异常之前完成了 Tasks.WaitAll 方法
-
在您的“外部”创建任务和 GenerateReport 方法之间有我们看不到的代码,我猜如果没有发布完整的代码链,您正在其他地方捕获。
标签: c# .net task threadpool