Why does the use of blocks prevent swallowing?
I recently ran into an exception handling problem when using an operator. The problem is that exceptions that are thrown inside a "using block" can be internalized, for example look at the code:
class DisposableObject : IDisposable
{
public void Dispose()
{
throw new Exception("dispose");
}
}
class Program
{
static void Main()
{
try
{
using (var obj = new DisposableObject())
{
throw new Exception("using");
}
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
In this example, you will see "dispose" in the output, the first exception will be ignored and you will never know about it. After some searching, I found an article https://msdn.microsoft.com/en-us/library/aa355056(v=vs.110).aspx about common usage errors using block. But my question is not how to avoid swallowing exceptions, I "want to know why MS decided to expand the block with
try
{
...
}
finally
{
}
and not otherwise, for example, they can be unpacked using the following:
//this code prevents exception swallowing
try
{
...
}
catch (Exception ex)
{
try
{
if (obj != null)
obj.Dispose();
}
catch (Exception disposeEx)
{
throw new AggregateException(ex, disposeEx);
}
throw;
}
if(obj != null)
obj.Dispose();
source to share
Because it AggregateException
didn't exist when the block was created using()
.
Also because you Dispose()
really shouldn't throw yourself.
Finally, because finally
there are subtle semantic differences between your example and the block , regarding exception filters, stack expansion, and critical areas.
source to share