使用任务管理线程异常

本文关键字:异常 线程 任务管理 | 更新日期: 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)
    {
        ...
    }
}