C#无法捕获同一解决方案中另一个项目的异常

时间:2016-06-27 13:47:32

标签: c# wpf exception-handling visual-studio-2015

遇到一个奇怪的问题:在我正在处理的复杂相机控制程序中,我使用的是带有C#包装器的SDK,这是由其他人编写的。我将包装器作为一个单独的项目包含在同一个解决方案中。我自己的代码是一个WPF项目,它使用了大量的SDK调用。

同步的一切都很好。但是,根据相机的响应,SDK偶尔会发送异步响应,通常以抛出相关报告错误信息的自定义异常的形式发送。我用

实现了这个

try { ... } catch (ThisExceptionType) { ... }

然而,没有任何例外被抓住。当异常情况发生时,VisualStudio会中断,向我显示SDK抛出它的代码并报告“ThisExceptionType未被用户代码处理”,同时显示异常条件的详细信息(意味着它显然已被正确抛出)。我验证了异常与我创建的错误条件相对应,所以我确定我没有查看代码的错误部分。

出于测试目的,我还将SDK中的行替换为ThisExceptionType引发标准异常,例如throw new ArgumentException("Test");相同结果:将我的catch更改为catch (ArgumentException)时,我仍然无法捕获条件并获得类似的未处理的用户代码错误。

以下是SDK如何抛出异常:

void CallEntryPoint( ...)
    {
        eNkMAIDResult result = _md3.EntryPoint(...);

        switch (result)
        {
            // Note: Ignore these return values
            case eNkMAIDResult.kNkMAIDResult_NoError:
            case eNkMAIDResult.kNkMAIDResult_Pending:
                break;

            default:
                throw new NikonException(...);
        }
    }

我在这里缺少什么?很抱歉,如果这是一个简单的问题 - 我在一般编程方面经验丰富,但在VisualStudio方面没有太多经验,而且在C#中也没有那么多。

UPDATE :根据包装的作者(实际上是Thomas Dideriksen's Nikon SDK wrapper),“当您编写WPF或WinForms应用程序时,C#包装器依赖于固有的Windows消息队列在UI线程上触发事件。“

他还声明包装器按顺序处理所有摄像头任务,所以我猜我的声明对于抛出异步异常的包装器是不正确的 - 包装器的所有代码示例都使用相同的try { ... } catch (ThisExceptionType) { ... }方法。为了更好地衡量,我尝试了一些建议,例如将处理程序挂钩到AppDomain.CurrentDomain.UnhandledException,但该方法也未能捕获异常。

为什么会出现这种情况还有其他想法?

1 个答案:

答案 0 :(得分:1)

MSDN上的这篇文章可能有所帮助。 https://msdn.microsoft.com/en-us/library/dd997415(v=vs.110).aspx

使用C#中的Tasks处理异常存在差异。希望这会减少您可以用来适当处理异常的不同技术。

来自MSDN文章:

  

正在运行的用户代码引发的未处理异常   任务内部传播回调用线程,除了   本主题后面介绍的某些方案。例外   当您使用静态或实例Task.Wait或其中一个时传播   Task.Wait方法,你通过封闭调用来处理它们   在try / catch语句中。如果任务是附加子项的父项   任务,或者如果您正在等待多个任务,则有多个例外   可能会被抛出。

并且提供了几种解决方案:

using System;
using System.Threading.Tasks;

public class Example
{
   public static void Main()
   {
      var task1 = Task.Run( () => { throw new CustomException("This exception is expected!"); } );

      try
      {
          task1.Wait();
      }
      catch (AggregateException ae)
      {
          foreach (var e in ae.InnerExceptions) {
              // Handle the custom exception.
              if (e is CustomException) {
                  Console.WriteLine(e.Message);
              }
              // Rethrow any other exception.
              else {
                  throw;
              }
          }
      }
   }
}

public class CustomException : Exception
{
   public CustomException(String message) : base(message)
   {}
}
// The example displays the following output:
//        This exception is expected!

或者你可以这样做:

using System;
using System.Threading.Tasks;

public class Example
{
   public static void Main()
   {
      var task1 = Task.Run( () => { throw new CustomException("This exception is expected!"); } );

      while(! task1.IsCompleted) {}

      if (task1.Status == TaskStatus.Faulted) {
          foreach (var e in task1.Exception.InnerExceptions) {
              // Handle the custom exception.
              if (e is CustomException) {
                  Console.WriteLine(e.Message);
              }
              // Rethrow any other exception.
              else {
                  throw e;
              }
          }
      }
   }
}

public class CustomException : Exception
{
   public CustomException(String message) : base(message)
   {}
}
// The example displays the following output:
//        This exception is expected!

我希望有所帮助!