相关疑难解决方法(0)

一次捕获多个异常?

不鼓励简单地抓住System.Exception.相反,只应捕获"已知"异常.

现在,这有时会导致不必要的重复代码,例如:

try
{
    WebId = new Guid(queryString["web"]);
}
catch (FormatException)
{
    WebId = Guid.Empty;
}
catch (OverflowException)
{
    WebId = Guid.Empty;
}
Run Code Online (Sandbox Code Playgroud)

我想知道:有没有办法捕获两个异常并且只WebId = Guid.Empty调用一次呼叫?

给出的例子相当简单,因为它只是一个GUID.但是想象一下你多次修改一个对象的代码,如果其中一个操作以预期的方式失败,你想要"重置"它object.但是,如果出现意外异常,我仍然希望将其提高.

.net c# exception-handling exception

2015
推荐指数
24
解决办法
52万
查看次数

为什么在C#中捕获并重新抛出异常?

我正在查看文章C# - 可序列化DTO上的数据传输对象.

这篇文章包括这段代码:

public static string SerializeDTO(DTO dto) {
    try {
        XmlSerializer xmlSer = new XmlSerializer(dto.GetType());
        StringWriter sWriter = new StringWriter();
        xmlSer.Serialize(sWriter, dto);
        return sWriter.ToString();
    }
    catch(Exception ex) {
        throw ex;
    }
}
Run Code Online (Sandbox Code Playgroud)

本文的其余部分看起来很合理(对于菜鸟),但是try-catch-throw会抛出一个WtfException ... 这不完全等同于根本不处理异常吗?

人机工程学:

public static string SerializeDTO(DTO dto) {
    XmlSerializer xmlSer = new XmlSerializer(dto.GetType());
    StringWriter sWriter = new StringWriter();
    xmlSer.Serialize(sWriter, dto);
    return sWriter.ToString();
}
Run Code Online (Sandbox Code Playgroud)

或者我错过了C#中错误处理的基本内容?它与Java几乎相同(减去已检查的异常),不是吗?......也就是说,他们都改进了C++.

Stack Overflow问题重新抛出无参数捕获和不执行任何操作之间的区别?似乎支持我的观点,即try-catch-throw是一个无操作.


编辑:

只是为了总结未来发现这个主题的人...

不要

try {
    // Do stuff that might throw an …
Run Code Online (Sandbox Code Playgroud)

c# exception-handling try-catch

528
推荐指数
9
解决办法
21万
查看次数

在C#中重新抛出异常的正确方法是什么?

我有一个问题,源于我的伙伴以不同于我的方式做事.

这样做更好:

try
{
    ...
}
catch (Exception ex)
{
    ...
    throw;
}
Run Code Online (Sandbox Code Playgroud)

或这个:

try
{
    ...
}
catch (Exception ex)
{
    ...
    throw ex;
}
Run Code Online (Sandbox Code Playgroud)

他们做同样的事情吗?这个比那个好吗?

.net c# exception-handling

435
推荐指数
7
解决办法
18万
查看次数

捕获和重新抛出.NET异常的最佳实践

捕获异常并重新抛出异常时需要考虑哪些最佳实践?我想确保保留Exception对象InnerException和堆栈跟踪.以下代码块在处理此方式时是否存在差异?

try
{
    //some code
}
catch (Exception ex)
{
    throw ex;
}
Run Code Online (Sandbox Code Playgroud)

VS:

try
{
    //some code
}
catch
{
    throw;
}
Run Code Online (Sandbox Code Playgroud)

.net c# exception-handling rethrow

279
推荐指数
8
解决办法
18万
查看次数

堆栈跟踪上的行号错误

我有这个代码

try
{
  //AN EXCEPTION IS GENERATED HERE!!!
}
catch  
{
   SqlService.RollbackTransaction();
   throw;
}

上面的代码在此代码中调用

try
{
  //HERE IS CALLED THE METHOD THAT CONTAINS THE CODE ABOVE
}
catch (Exception ex)
{
   HandleException(ex);
}

作为参数传递给方法"HandleException"的异常包含堆栈跟踪中"throw"行的行号,而不是生成异常的实际行.任何人都知道为什么会发生这种情况?

编辑1 好的,谢谢大家的答案.我更改了内部捕获


catch(Exception ex)
{
    SqlService.RollbackTransaction();
    throw new Exception("Enrollment error", ex);
}

现在我在堆栈跟踪上有正确的行,但我不得不创建一个新的异常.我希望找到更好的解决方案:-(

EDIT2 也许(如果你有5分钟)你可以尝试这种情况,以检查你是否得到相同的结果,而不是很复杂的重新创建.

c# exception-handling try-catch

30
推荐指数
4
解决办法
7394
查看次数

如何在不丢失堆栈跟踪的情况下重新抛出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
查看次数

如何在保持到目前为止生成的堆栈跟踪的同时重新抛出内部异常?

重复:在C#中,如何在不丢失堆栈跟踪的情况下重新抛出InnerException?

我有一些操作,我在后台线程上异步调用.有时,事情变坏了.当发生这种情况时,我倾向于得到一个TargetInvocationException,这在适当的时候是没用的.我真正需要的是TargetInvocationException的InnerException,如下所示:

    try
    {
        ReturnValue = myFunctionCall.Invoke(Target, Parameters);
    }
    catch (TargetInvocationException err)
    {
        throw err.InnerException;
    }
Run Code Online (Sandbox Code Playgroud)

这样,我的调用者就会发生真正的异常.问题是,throw语句似乎重置了堆栈跟踪.我想基本上重新抛出内部异常,但保留它最初的堆栈跟踪.我怎么做?

澄清: 我只想要内部异常的原因是这个类试图"抽象"这些函数(由调用者提供的委托)在其他线程上运行的事实.如果存在异常,则可能与在后台线程上运行无关,并且调用者真的希望堆栈跟踪进入其委托并找到真正的问题,而不是我调用的调用.

.net c# exception-handling exception stack-trace

19
推荐指数
3
解决办法
4854
查看次数

什么是用于捕获SQLException和重试的优秀C#编码样式

我有一个方法调用SQLServer函数对表执行自由文本搜索.该函数有时会在第一次调用时导致SQLException:"全文查询字符串的单词分解超时".所以我通常想重试该请求,因为它会在后续请求中成功.构造重试逻辑的好方法是什么.目前我有以下内容:

var retryCount = 0;
var results = new List<UserSummaryDto>();
using (var ctx = new UsersDataContext(ConfigurationManager.ConnectionStrings[CONNECTION_STRING_KEY].ConnectionString))
{
    for (; ; )
    {
        try
        {
            results = ctx.SearchPhoneList(value, maxRows)
                         .Select(user => user.ToDto())
                         .ToList();
            break;
        }
        catch (SqlException)
        {
            retryCount++;
            if (retryCount > MAX_RETRY) throw;
        }
    }
}

return results;
Run Code Online (Sandbox Code Playgroud)

c# sql linq

19
推荐指数
4
解决办法
2万
查看次数

没有堆栈跟踪的异常 - 如何?

我们有一项服务,它将在应用程序域级别(通过Log4net)记录未处理的异常.

我们记录了:

2014-01-28 16:49:19,636 ERROR [49] FeedWrapperService - 未处理的System.NullReferenceException:未将对象引用设置为对象的实例.

此异常没有堆栈跟踪.如果不对异常对象做一些疯狂的事情,这怎么可能呢?

我们的处理代码:

AppDomain.CurrentDomain.UnhandledException += LogAnyExceptions;

private void LogAnyExceptions(object sender, UnhandledExceptionEventArgs e)
{
    log.Error("unhandled", (Exception)e.ExceptionObject);
    throw (Exception)e.ExceptionObject;
}
Run Code Online (Sandbox Code Playgroud)

在我看来,重新抛出这一点毫无意义,因为AppDomain无论如何都会随着进程而下降,但我认为它不会影响我们的情况.

Windows应用程序事件查看器也只显示此null ref异常并且没有跟踪.

我已经测试了异常处理程序日志记录,它成功记录了堆栈跟踪和任何内部异常.如果它被我们的代码抛出,我们会看到堆栈跟踪.如果它被第三方c#库抛出,那么,我们再次看到至少一个方法的堆栈跟踪(无论是否是重新抛出的异常).在这里,我们看到一个没有堆栈跟踪的托管异常.我不知道这是怎么可能的.

查看反编译的第三方库,它与非托管代码进行对话,引发此异常的事件可能在非托管域中,但是如果没有堆栈跟踪,这种情况怎么会导致托管的空引用异常?

这个问题的原因是间歇性的.我们已经将这段代码在生产中运行了几个月,并且看过它曾经这样做过.这非常怪异.

普遍的共识是,应该将负责此类问题的系统推送到子进程中,这样我们就可以处理问题并安全地自动重启,但知道发生了什么事情会很好.

编辑以包含以下评论信息:

我的异常不是标准的重新抛出,因为堆栈跟踪是null或空.它没有重新投掷方法的名称.进一步挖掘,Exception类可以从序列化信息构造,看起来序列化信息可能包含堆栈跟踪的空字符串,并且可能创建它而不会导致其他错误.我想它可能来自那里,但我不知道它是如何起源的.

c# exception stack-trace unhandled-exception

17
推荐指数
3
解决办法
1万
查看次数

保留动态调用方法的异常

我想动态调用一个MethodInfo对象,并且从它内部抛出的任何异常向外传递,就像它被正常调用一样.

我看来有两种选择.它们概述如下.

选项1保持抛出的异常的类型MyStaticFunction,但是StackTrace因为它而被破坏throw.

选项2维护StackTrace异常,但异常的类型始终如此TargetInvocationException.我可以提取InnerException它的类型,但这意味着我不能写这个例子:

try { DoDynamicCall(); }
catch (MySpecialException e) { /* special handling */ }
Run Code Online (Sandbox Code Playgroud)

选项1:

void DoDynamicCall()
{
    MethodInfo method = /*referencing MyClass method void MyStaticFunction(int x)*/;
    try
    {
        method.Invoke(null, new object[] { 5 });
    }
    catch (TargetInvocationException e)
    {
        throw e.InnerException;
    }
}
Run Code Online (Sandbox Code Playgroud)

选项2:

void DoDynamicCall()
{
    MethodInfo method = /*referencing MyClass method void MyStaticFunction(int x)*/;
    method.Invoke(null, new …
Run Code Online (Sandbox Code Playgroud)

c# reflection exception

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