遇到一个奇怪的问题:在我正在处理的复杂相机控制程序中,我使用的是带有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
,但该方法也未能捕获异常。
为什么会出现这种情况还有其他想法?
答案 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!
我希望有所帮助!