I recently ran into a problem with exception handling in using statement. The problem is that exceptions which throws inside 'using block' could swallowed, for example look at 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 output, first exception will be ignored and you will never know about it. After some searching i found article https://msdn.microsoft.com/en-us/library/aa355056(v=vs.110).aspx about common mistakes about use using block. But my question isn't about how to avoid exception swallowing, i' want to know why MS decided to unwrap using block to
try
{
...
}
finally
{
}
and not the otherwise, for example they could unwrap using to something like this:
//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();
Because
AggregateException
didn't exist when theusing()
block was created.Also because
Dispose()
is really not supposed to throw.Finally, because there are subtle semantic differences between your example and a
finally
block, with regard to exception filters, stack unwinding, and critical regions.