在Silverlight中重新抛出异常时保留堆栈跟踪

5
我需要重新抛出一个已被捕获并存储在其他位置的异常,同时不丢失有关第一次捕获/存储异常时的堆栈跟踪信息。我的代码大致如下:
    public void Test()
    {
        int someParameter = 12;
        ExecuteSomeAsyncMethod(someParameter, CallbackMethod);   
    }

    public void CallbackMethod(object result, Exception error)
    {
        //Check for exceptions that were previously caught and passed to us
        if(error != null)
            //Throwing like this will lose the stack trace already in Exception
            //We'd like to be able to rethrow it without overwriting the stack trace
            throw error;

        //Success case: Process 'result'...etc...
    }

我看到解决此问题的方法使用了反射(例如这里这里),或使用序列化(例如这里),但在Silverlight中,这些方法都无法使用(私有反射不被允许,而在序列化方法中使用的类/方法在Silverlight中不存在)。
是否有任何方法可以在Silverlight中保留堆栈跟踪?
2个回答

3

使用现有的异常作为内部异常,抛出一个新的异常:

throw new ApplcationException("Error message", error);

内部异常将保留其堆栈跟踪。

目前看来这似乎是我唯一的选择。不幸的是,这可能会干扰现有的代码,比如“catch(SpecificExceptionClass)”或者其他检查异常类型的代码。理想情况下,如果可能的话,我希望避免包装异常,因为我不希望消费者必须开始检查InnerExceptions以获取“真正”的异常信息。 - Stephen McDaniel

3

你可以使用以下任一种方式:

catch(Exeption)
{
   throw;
}

或者
catch(Exception e)
{
   throw new Exception(e);
}

两种解决方案都会保留堆栈跟踪。第一种解决方案在您的示例中似乎不可行,但第二种应该可以工作。

当然,在您的情况下,您需要抛出参数error而不是e


如果你想提到所有不起作用的可能解决方案,那么你忘记了最简单的解决方案:根本不捕获异常。 ;) - Guffa
@Guffa,没错...但是如果这样做,他在异常发生时似乎就无法执行任何逻辑了。我之所以同时提到这两种情况,是因为简单重写代码可能会使第一种情况更具吸引力。但你当然是对的,不捕获异常会防止它被捕获:)。 - Jesper Fyhr Knudsen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接