[英]Why exception filters are preferable to catching and rethrowing?
基於此問題 (新的Exception filter
功能提供了什么好處?)。
該聲明:
異常過濾器比捕獲和重新拋出更可取,因為它們不會破壞堆棧。 如果異常之后導致堆棧被轉儲,則可以看到堆棧最初來自何處,而不僅僅是堆棧被重新拋出的最后一個位置。
做一些測試后,我沒有看到這兩個之間的區別,新與舊,我還看到有人重新拋出的地方除外。 因此,或者信息未被確認,我不理解“異常”過濾器(這就是我要問的原因),或者我做錯了。 你能解釋一下為什么這個動作過濾器是一個優勢嗎?
class specialException : Exception
{
public DateTime sentDateTime { get; } = DateTime.Now;
public int code { get; } = 0;
public string emailsToAlert { get; } = "email@domain.com";
}
然后:
try
{
throw new specialException(); //line 16
throw new Exception("Weird exception");
//int a = Int32.Parse("fail");
}
catch (specialException e) when(e.code == 0)
{
WriteLine("E.code 0");
throw; // <-Line 23
}
catch (FormatException e)
{
WriteLine("cond1 " + e.GetBaseException().Message+" "+e.StackTrace);
throw;
}
catch (Exception e) //when (cond2)
{
Console.WriteLine("cond2! " + e.Message);
throw;
}
結果:
異常過濾的優點更多是與過濾器不匹配有關,而不是與過濾器不匹配有關。 如果刪除除第一個catch
塊以外的所有catch
塊,並將第一個catch
塊上的過濾器更改為when(e.code != 0)
,則異常的調用堆棧將表明它已在第16行上拋出。
實現此目標的舊方法如下:
try
{
throw new specialException(); //line 16
throw new Exception("Weird exception");
//int a = Int32.Parse("fail");
}
catch (specialException e)
{
if(e.code != 0)
{
WriteLine("E.code isn't 0");
return;
}
throw;
}
在這種情況下,調用堆棧將指示該異常是在throw
語句而不是第16行上throw
。
我將為您提供一個很好的真實示例,該示例已用於該示例:死鎖重試循環。
有些API很好,並且具有特定的DeadlockException
類的東西;而其他API,例如SOAP代理,則不盡然。 如果您沒有,則異常過濾器可以很好地避免需要重新拋出。
int retryCount = 0;
while(true)
{
try
{
// do stuff.
break;
}
catch(Exception ex) when(ex.Message == "Deadlock" && ++retryCount < 10)
{
// retry up to 10 times.
continue;
}
}
這樣可以避免在發生非死鎖異常或達到重試限制時不必引發包裝異常的情況。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.