我正在设计一个长时间运行的数据流水线,由多个块组成。项被送到管道的输入块中,最终通过它并在UI中显示(作为对用户的礼貌,但管道的真正工作是将处理结果保存到磁盘中)。
管道块内的lambda函数可能会因各种原因(错误的输入、网络故障、计算过程中出错等)而抛出异常。在这种情况下,我希望将有问题的项排除,并在UI下方的“错误”部分显示它。
那么最好的方法是什么?我知道可以在每个单独的lambda函数中使用try/catch来实现:
var errorLoggingBlock = new ActionBlock<Tuple<WorkItem, Exception>>(...)
var workerBlock = new TransformBlock<WorkItem, WorkItem>(item =>
{
try {
return DoStuff(item);
} catch (Exception ex) {
errorLoggingBlock.SendAsync(Tuple.Create(item, ex));
return null;
}
}
但是我有大约10个块在管道中,把那段代码复制/粘贴到每一个块中似乎很愚蠢。而且,我不喜欢返回null的想法,因为现在所有下游块都将不得不检查它。
我的下一个最好的想法是创建一个函数,返回一个lambda表达式来替代我进行包装:
private Func<TArg, TResult> HandleErrors<TArg, TResult>(Func<TArg, TResult> f) where TArg:WorkItem
{
return arg =>
{
try {
return f(arg);
} catch (Exception ex) {
errorLoggingBlock.SendAsync(Tuple.Create(item, ex));
return default(TResult);
}
};
}
但这似乎有点太元了。有更好的方法吗?
Try
库。它允许将消息通过管道的所有块,并在最后观察到此消息发生的任何异常。 - Theodor Zoulias