Intercepting an exception inside IDisposable.Dispose

前端 未结 11 1858
有刺的猬
有刺的猬 2020-12-13 02:07

In the IDisposable.Dispose method is there a way to figure out if an exception is being thrown?

using (MyWrapper wrapper = new MyWrapper())
{
           


        
11条回答
  •  误落风尘
    2020-12-13 02:32

    It is not possible to capture the Exception in the Dispose() method.

    However, it is possible to check Marshal.GetExceptionCode() in the Dispose to detect if an Exception did occur, but I wouldn't rely on that.

    If you don't need a class and want just want to capture the Exception, you can create a function that accepts a lambda that is executed within a try/catch block, something like this:

    HandleException(() => {
        throw new Exception("Bad error.");
    });
    
    public static void HandleException(Action code)
    {
        try
        {
            if (code != null)
                code.Invoke();
        }
        catch
        {
            Console.WriteLine("Error handling");
            throw;
        }
    }
    

    As example, You can use a method that automatically does a Commit() or Rollback() of a transaction and do some logging. At this way you don't always need a try/catch block.

    public static int? GetFerrariId()
    {
        using (var connection = new SqlConnection("..."))
        {
            connection.Open();
            using (var transaction = connection.BeginTransaction())
            {
                return HandleTranaction(transaction, () =>
                {
                    using (var command = connection.CreateCommand())
                    {
                        command.Transaction = transaction;
                        command.CommandText = "SELECT CarID FROM Cars WHERE Brand = 'Ferrari'";
                        return (int?)command.ExecuteScalar();
                    }
                });
            }
        }
    }
    
    public static T HandleTranaction(IDbTransaction transaction, Func code)
    {
        try
        {
            var result = code != null ? code.Invoke() : default(T);
            transaction.Commit();
            return result;
        }
        catch
        {
            transaction.Rollback();
            throw;
        }
    }
    

提交回复
热议问题