1

短版:异常视为用户未处理的,即使它处理

为什么Visual Studio中告诉我,该代码已抛出用户未处理的异常,即使我捕捉到了异常?

加长版:

我使用实体框架与Microsoft's transient fault handling framework在一起:

我的实体框架类是局部的,我有我自己的方法SaveChangesWithRetries哪里进行重试逻辑:

public partial class EfContext 
{ 
    public virtual void SaveChangesWithRetries() 
    { 
     var retryPolicy = RetryPolicyFactory.GetDefaultSqlCommandRetryPolicy(); 
     retryPolicy.ExecuteAction(() => 
         { 
          SaveChanges(); 
         }); 
    } 
} 

我的代码使用这个功能可能如下所示:

try 
{ 
    context.SaveChangesWithRetries(); 
} 
catch (OptimisticConcurrencyException) 
{ 
    continue; 
} 

即使我发现了OptimisticConcurrencyException异常,Visual Studio会停止调试器并告诉我对ExecuteAction()的调用会抛出用户未处理的异常。发生这种情况时,调试器停止在EfContext类中。如果我按下F10,调试器会转到catch(OptimisticConcurrencyException)。

我不明白为什么VS2010告诉我有一个用户未处理的异常,即使我有一个catch,即使我的catch捕获异常。

+1

这是什么'继续'在你的'catch'做? – Oded 2012-04-02 13:16:46

回答

1

找出造成这种情况的原因。

  1. 我们的代码开始一个try/catch子句
  2. 我们的代码称为瞬态故障处理框架(TFHF)
  3. TFHF叫我们的代码(通过拉姆达expression9
  4. 我们的代码抛出异常

由于TFHF是在发行版中构建的,因此.NET Framework不理解我们自己的代码在第3步中引发的第0步中发生异常。

0

我有一个类似的问题,我需要通过一些.NET代码来传播异常,以便我可以在另一边捕获它。我发现Debug> Exceptions对话框允许你选择你希望VS打破的异常类型。对于每种异常类型,您可以检查是否在抛出异常时或者仅在未处理时才中断。所以,我所做的是选择一个深奥的异常类型,默认情况下未选中“user-unhandled”并包装我想用这种类型的异常传播的异常。特别是,我选择了AppDomainUnloadedException,因为它在System.dll程序集中,因此已经被我的项目引用。

这里是我的代码,它包装IOException异常,我需要传播:

public override int Read(byte[] buffer, int offset, int count) 
{ 
    try { return innerStream.Read(buffer, offset, count); } 
    catch (IOException ex) { throw new AppDomainUnloadedException("Exception from innerStream: " + ex.Message, ex); } 
} 

这是我的代码,在那里我抓住它,它需要传播通过.NET代码的另一面:

try { bytesRead = sslStream.Read(buffer, offset, count); } 
catch (Exception ex) { /* ex handled here. */ } 

问题解决了。 VS不再在innerStream上抛出,抛出IOException异常时读取。

+1

这似乎是一个丑陋的解决方案,迟早会造成混乱。 :) – Nitramk 2013-01-20 12:18:00

+0

这确实是一个黑客攻击,但它确实有效,这使得它比没有好。就未来的混乱而言,这就是我们为什么会发表意见的原因。 :) – reirab 2013-01-21 14:28:42