2016-06-27 20 views
0

奇妙な問題がありました。私が取り組んでいる複雑なカメラ制御プログラムでは、他の人がプログラミングしたC#ラッパーを使用してSDKを使用します。ラッパーを同じソリューション内の別のプロジェクトとして組み込みます。自分のコードは、SDKへの多数の呼び出しを使用するWPFプロジェクトです。C#同じソリューション内の別のプロジェクトから例外をキャッチできません。

すべての同期が正常に動作します。ただし、カメラの応答に応じて、SDKは非同期応答を送信することがあります。通常、カメラが報告するエラーに関する情報を含むカスタム例外をスローします。私はしかし、例外がこれまでにキャッチされなかっます

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

を使用して、これを実装しました。例外状況が発生すると、VisualStudioがブレークし、SDKがスローしたコードが表示され、「ThisExceptionTypeはユーザーコードによって未処理です」というレポートが表示され、例外条件の詳細が表示されます(正しくスローされたことを意味します)。例外が私が作成したエラー条件に対応することを確認したので、私のコードの間違った部分を見ていないと確信しています。テスト目的のために

は、私はまた、このようなthrow new ArgumentException("Test");同じ結果として、それは標準の例外を除いてThisExceptionTypeをスローSDKで行を置き換え:catch (ArgumentException)に私のキャッチを変更するとき、私はまだ条件をキャッチし、同様のunhandled-を取得することはできませんユーザコード別エラー。ここで

は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#のラッパーは、UIスレッド上のイベントを発生する固有のWindowsメッセージキューに依存しています。」

また、ラッパーはすべてのカメラタスクを順番に処理するので、私のステートメントは非同期例外をスローするラッパーについて間違っていたとも言われています - ラッパーのすべてのコード例は同じtry { ... } catch (ThisExceptionType) { ... }アプローチを使用します。良い対策のために、ハンドラをAppDomain.CurrentDomain.UnhandledExceptionにフックするなど、いくつかの提案を試みましたが、そのアプローチでも例外をキャッチできませんでした。

これがなぜ起こっているのでしょうか?

+2

問題は非同期処理です。他のスレッドからの例外は、メインスレッド内で捕捉されません。 [this](http://stackoverflow.com/questions/5983779/catch-exception-that-is-thrown-in-different-thread)のようなこのトピックに関する多くの投稿があります –

+0

私はあなたが非同期メッセージングを処理すると思いますイベント経由で。あなたはコードを投稿できますか? –

+0

"SDKはときどき*非同期*応答を送信します":tryとcatchの間に実際に例外がスローされないように見えます。 SDKと対話するコードを含めることはできますか?私は、あなたのコードは、SDKをオフにし、そのことを行う何かを行う必要があり、最終的に例外をスローすると仮定します。 'Task' /' async'を使用するSDKの最新コードでは、 '' await'の周りにtry/catchを投げることができるはずです(http://stackoverflow.com/a/19865613/424129)。 –

答えて

1

この記事はMSDNでも役に立ちます。 https://msdn.microsoft.com/en-us/library/dd997415(v=vs.110).aspx

C#のタスクを使用して例外を処理する点に違いがあります。うまくいけば、例外を適切に処理するために使うことができるさまざまなテクニックを実行することができます。このトピックの後半で説明されている 特定のシナリオを除き、呼び出し元のスレッドに伝播されたタスクの内部 を実行しているユーザーコードによってスローされ

未処理の例外: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! 

私はそれが役に立てば幸い!

+0

初心者の皆様、とても素早く対応してくれてありがとうございます。私はC#のタスクのスレッドを読む必要があると思う - これは私が前に使用したものではありません。明確にするために、私が受け取っている可能性のある例外は、定期的な応答ではなく、エラーメッセージです。何も返ってこないかもしれないので、私は何の解決策も使用できません。 – Lon

関連する問題