c#无法在同一解决方案中捕获来自另一个项目的异常

本文关键字:另一个 项目 异常 解决方案 | 更新日期: 2023-09-27 17:52:11

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

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

实现了这个

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

然而,没有异常被捕获。当异常情况发生时,VisualStudio中断,向我显示SDK抛出它的代码并报告"ThisExceptionType未被用户代码处理",还显示异常条件的详细信息(意味着它显然被正确抛出)。我验证了异常与我创建的错误条件相对应,因此我确信我没有看到错误的代码部分。

出于测试目的,我还替换了SDK中抛出ThisExceptionType的行,其中包含标准异常,例如throw new ArgumentException("Test");。相同的结果:当将捕获更改为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的尼康SDK包装器),"当您编写WPF或WinForms应用程序时,c#包装器依赖于固有的windows消息队列来在UI线程上触发事件。"

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

还有其他原因吗?

c#无法在同一解决方案中捕获来自另一个项目的异常

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

在c#中使用任务处理异常是不同的。希望这将给你一个不同的技术运行,你可以使用适当地处理异常。

来自MSDN文章:

由正在运行的用户代码抛出的未处理异常在任务内部传播回调用线程,但在本主题后面将描述的某些场景。异常在使用静态任务或实例任务时传播。等待或的任务。方法,通过封装调用来处理它们在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!

我希望这对你有帮助!