问题
Based on this question (What benefit does the new Exception filter
feature provide?).
The statement:
Exception filters are preferable to catching and rethrowing because they leave the stack unharmed. If the exception later causes the stack to be dumped, you can see where it originally came from, rather than just the last place it was rethrown.
after doing some testing, I did not see the difference between both, the old and the new, I still see the exception from the place it was rethrown. So, or the information is not confirmed, I don't understand the Exception filters( that is why I am asking), or I am doing it wrong. Can you explaing me why this action filter are an advantage?
class specialException : Exception
{
public DateTime sentDateTime { get; } = DateTime.Now;
public int code { get; } = 0;
public string emailsToAlert { get; } = "email@domain.com";
}
then:
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;
}
Result:
回答1:
The advantages of exception filtering are more to do with when the filter doesn't match, not when it does match. If you remove all of the catch
blocks except for the first one, and change the filter on the first catch
block to when(e.code != 0)
, then the callstack of the exception would indicate it was thrown on line 16.
The old way of implementing this would be as follows:
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;
}
In this case, the call stack will indicate that the exception was thrown at the throw
statement, rather than on line 16.
回答2:
I'll give you a good real world example that I've used it for: deadlock retry loops.
Some APIs are nice and have a specific DeadlockException
sort of thing -- others, like SOAP proxies, not quite. When you don't have one, exception filters are great to avoid needing to rethrow.
int retryCount = 0;
while(true)
{
try
{
// do stuff.
break;
}
catch(Exception ex) when(ex.Message == "Deadlock" && ++retryCount < 10)
{
// retry up to 10 times.
continue;
}
}
This saves you from having to throw a wrapper exception if a non-deadlock exception happens, or if the retry limit is hit.
来源:https://stackoverflow.com/questions/32638310/why-exception-filters-are-preferable-to-catching-and-rethrowing