将线程添加到集合时处理 TPL 中的错误
Handeling errors in the TPL when I am adding threads to a collection
我正在研究生产者消费者模型,其中生产的每个项目都在新的任务并行库线程上使用,并在 List<Task>
集合中进行跟踪。我希望能够及时且可预测地捕获任何未处理的异常。在一个循环中,我从集合中删除了完成的线程,并且正在考虑类似以下的内容,但没有在网上看到任何关于此的内容。
try
{
Task.WaitAll(threadList.FindAll(x => x.IsFaulted).ToArray());
}
catch(AggregateException aex)
{
//Deal with the exceptions and possibly kill the program
}
threadList.RemoveAll(x => x.IsCompleted);
由于在子线程中进行了良好的错误处理,因此除了 OutOfMemoryException 之类的情况外,永远不会出现未处理的异常。如果发生这种情况,我想抓住它并通过日志记录优雅地死去。
是否有更好的选择或设计我应该考虑?
您可能需要考虑在循环中使用 Task.WaitAny
(删除已完成的任务)。
这样做的好处是可以在异常发生时向您显示(处理您的"timely manner"要求),而不是等待所有任务完成提前。
我会采取稍微不同的方法。
我会等待每个任务独立完成,并在任务完成时递减列表:
while (threadList.Count > 0)
{
Task finishedTask;
try
{
finishedTask = await Task.WhenAny(threadList);
// More processing if needed.
}
catch (Exception e)
{
// Handle exception.
}
finally
{
threadList.Remove(finishedTask);
}
}
请注意,通过这种方式您可以捕获特定的异常,而让其他异常未处理。
作为旁注 - 查看 TPL Dataflow。线程模型和异常传播已为您处理。
我正在研究生产者消费者模型,其中生产的每个项目都在新的任务并行库线程上使用,并在 List<Task>
集合中进行跟踪。我希望能够及时且可预测地捕获任何未处理的异常。在一个循环中,我从集合中删除了完成的线程,并且正在考虑类似以下的内容,但没有在网上看到任何关于此的内容。
try
{
Task.WaitAll(threadList.FindAll(x => x.IsFaulted).ToArray());
}
catch(AggregateException aex)
{
//Deal with the exceptions and possibly kill the program
}
threadList.RemoveAll(x => x.IsCompleted);
由于在子线程中进行了良好的错误处理,因此除了 OutOfMemoryException 之类的情况外,永远不会出现未处理的异常。如果发生这种情况,我想抓住它并通过日志记录优雅地死去。
是否有更好的选择或设计我应该考虑?
您可能需要考虑在循环中使用 Task.WaitAny
(删除已完成的任务)。
这样做的好处是可以在异常发生时向您显示(处理您的"timely manner"要求),而不是等待所有任务完成提前。
我会采取稍微不同的方法。 我会等待每个任务独立完成,并在任务完成时递减列表:
while (threadList.Count > 0)
{
Task finishedTask;
try
{
finishedTask = await Task.WhenAny(threadList);
// More processing if needed.
}
catch (Exception e)
{
// Handle exception.
}
finally
{
threadList.Remove(finishedTask);
}
}
请注意,通过这种方式您可以捕获特定的异常,而让其他异常未处理。
作为旁注 - 查看 TPL Dataflow。线程模型和异常传播已为您处理。