相关疑难解决方法(0)

如何重新抛出InnerException而不会丢失C#中的堆栈跟踪?

我通过反射调用一种可能导致异常的方法.如何在没有包装器反射的情况下将异常传递给调用者?
我正在重新抛出InnerException,但这会破坏堆栈跟踪.
示例代码:

public void test1()
{
    // Throw an exception for testing purposes
    throw new ArgumentException("test1");
}

void test2()
{
    try
    {
        MethodInfo mi = typeof(Program).GetMethod("test1");
        mi.Invoke(this, null);
    }
    catch (TargetInvocationException tiex)
    {
        // Throw the new exception
        throw tiex.InnerException;
    }
}
Run Code Online (Sandbox Code Playgroud)

.net c# exception

290
推荐指数
9
解决办法
7万
查看次数

如何在不丢失堆栈跟踪的情况下重新抛出TargetInvocationException的内部异常

我有许多方法正在调用Delegate.DynamicInvoke.其中一些方法会进行数据库调用,我希望能够捕获一个SqlException而不是TargetInvocationException通过它的内部捕获并查找实际出错的方法.

我正在使用此方法重新抛出但它清除了堆栈跟踪:

 try
 {
      return myDelegate.DynamicInvoke(args);
 }
 catch(TargetInvocationException ex)
 {
     Func<TargetInvocationException, Exception> getInner = null;
     getInner =
        delegate(TargetInvocationException e)
        {
        if (e.InnerException is TargetInvocationException)
            return getInner((TargetInvocationException) e.InnerException);

         return e.InnerException;
        };

     Exception inner = getInner(ex);
     inner.PreserveStackTrace();
     throw inner;
 }
Run Code Online (Sandbox Code Playgroud)

这个PreserveStackTrace方法是我通过另一个帖子修复的扩展方法(我不知道它实际上做了什么).但是,这似乎不会保留跟踪:

public static void PreserveStackTrace(this Exception e)
{
    var ctx = new StreamingContext(StreamingContextStates.CrossAppDomain);
    var mgr = new ObjectManager(null, ctx);
    var si = new SerializationInfo(e.GetType(), new FormatterConverter());

    e.GetObjectData(si, ctx);
    mgr.RegisterObject(e, 1, si);
    mgr.DoFixups(); 
}
Run Code Online (Sandbox Code Playgroud)

c# exception-handling stack-trace targetinvocationexception inner-exception

20
推荐指数
1
解决办法
5427
查看次数

从存储过程catch块处理死锁重试是一个好主意

从我的承诺来看,不可能完全阻止交易陷入僵局.

我希望从应用程序代码的角度来看,交易永远不会失败.所以我已经看到这个模式用于Microsoft SQL,我想知道这是一个好主意吗?


    DECLARE @retry  tinyint
    SET @retry  = 5
    WHILE @retry >0
    BEGIN
      BEGIN TRANSACTION
      BEGIN TRY
        // do transaction her
        COMMIT
        BREAK
      END TRY
      BEGIN CATCH
        ROLLBACK

        if (ERROR_NUMBER() = 1205 OR ERROR_NUMBER() = 1222)
        BEGIN
          SET @retry = @retry - 1
          IF @retry = 0
             RAISEERROR('Could not complete transaction',16,1);
          WAITFOR DELAY '00:00:00.05' -- Wait for 50 ms
          CONTINUE
        END
        ELSE
        BEGIN
          RAISEERROR('Non-deadlock condition encountered',16,1);
          BREAK;
        END
      END CATCH;
    END

sql database sql-server deadlock

10
推荐指数
2
解决办法
1万
查看次数