Determine if executing in finally block due to exception being thrown

前端 未结 8 1252
遥遥无期
遥遥无期 2020-12-16 10:01

Is it possible to determine if code is currently executing in the context of a finally handler as a result of an exception being thrown? I\'m rather fond of usi

8条回答
  •  醉酒成梦
    2020-12-16 10:26

    It would be (IMHO very) helpful if there were a variant of IDisposable whose Dispose method accepted a parameter to indicate what exception, if any, was pending when it was run. Among other things, in the event that Dispose is unable to perform the expected cleanup, it would be able to throw an exception which includes information about the earlier exception. It would also allow a Dispose method to throw an exception if code "forgets" to do something that it was supposed to do within a using block, but not overwrite any other exception that might cause the using block to exit prematurely. Unfortunately, no such feature exists as of yet.

    There are numerous articles which suggest means of using API functions to find out whether a pending exception exists. One major problem with such approaches is that it is possible that code may be running in a finally block for a try which completed successfully, but that may be nested in a finally block whose try exited prematurely. Even if a Dispose method could identify that such a situation existed, it would have no way of knowing which try block it "belonged" to. One could formulate examples where either situation applies.

    As it is, the best approach is probably to have an explicit "success" method and assume failure if it's not called, and figure that the consequences of forgetting to call the "success" method should be obvious even if no exception is thrown. One thing that may be helpful as a simple utility method would be something like

    T Success(T returnValue)
    {
      Success();
      return T;
    }
    

    thus allowing code like:

    return scopeGuard.Success(thingThatMightThrow());
    

    rather than

    var result = thingThatMightThrow();
    scopeGuard.Success();
    return result;
    

提交回复
热议问题