我目前正在使用这种有点乏味的模式为运行一些长时间操作的用户生成错误消息:
string _problem;
void SomeLongRunningMethod()
{
try
{
_problem = "Method1 had problem";
Method1();
_problem = "Unexpected error during doing something in Method2";
if(Method2())
{
_problem = "Method3 fails";
Method3();
}
_problem = "Not possible to obtain data";
var somedata = Method4();
}
catch(Exception)
{
MessageBox.Show("Problem with some long running method: " + _problem);
}
}
任何一种方法都可能抛出,我想告诉用户发生哪一步失败。这可以通过在运行之前设置_problem
来完成。
在某些情况下,我可以使用不同的Exception
类型进行捕获,但这并不总是有效,例如Method1
和Method2
都可以throw InvalidOperationException()
。
这个重复的代码看起来像一个模式。虽然我无法认出来。有任何想法吗?如何提高可读性?
答案 0 :(得分:4)
您可以使用when
中的catch
来区分相同的异常类型,并检查哪种方法引发了此异常:
void SomeLongRunningMethod()
{
try
{
Method1();
if (Method2())
{
Method3();
}
var somedata = Method4();
}
catch (InvalidOperationException invEx) when (invEx.TargetSite?.Name == nameof(Method1))
{
// ...
}
catch (InvalidOperationException invEx) when (invEx.TargetSite?.Name == nameof(Method2))
{
// ...
}
catch (Exception ex)
{
// ...
}
}
答案 1 :(得分:2)
您可以使用error.TargetSite
获取导致异常的方法。您唯一需要改变的是您的追踪线:catch (Exception error)
答案 2 :(得分:1)
我会制作一系列您想要做的事情并贯穿它们:
var methodList = new[]{
new{action = (Action)Method1, identifier = "Method1"},
new{action = (Action)Method2, identifier = "Method2"},
new{action = (Action)Method3, identifier = "Method3"},
};
string problem = null;
foreach(var info in methodList)
{
try
{
info.action();
}
catch(InvalidOperationException)
{
problem = string.Format("{0} failed", info.identifier);
break;
}
}
if(problem != null)
{
//notify
}