2013-08-22 3 views
5

を管理しますが、私はまだそれを得ることはありませんDLLによって駆動されるRFIDリーダ。このDLLのソースコードはありませんが、使用方法を示すサンプルのみです。GCHandle、私が働いている</p> <p>....のAppDomainは「AppDomainを越えてGCHandleを渡すことはできません」私は例外についての多くのスレッドを見てきたコードやサードパーティ製のDLL

サンプルは素晴らしいですが、別のプロジェクトでコードをコピーして、ミドルウェアMicrosoft Biztalkにリーダーを追加する必要があります。

問題は、Microsoft Biztalkのプロセスが別のAppDomainで動作することです。リーダは、タグが読み取られたときのイベントを処理します。しかし、Microsoft Biztalkの下で実行すると、この迷惑な例外が発生します。

私はそれを動作させる方法に関するすべてのソリューションを見ることができない...

ここでは面白いかもしれいくつかのコードです:

// Let's connecting the result handlers. 
// The reader calls a command-specific result handler if a command is done and the answer is ready to send. 
// So let's tell the reader which functions should be called if a result is ready to send. 

// result handler for reading EPCs synchronous 
Reader.KSRWSetResultHandlerSyncGetEPCs(ResultHandlerSyncGetEPCs); 

[...] 

var readerErrorCode = Reader.KSRWSyncGetEPCs(); 
if (readerErrorCode == tKSRWReaderErrorCode.KSRW_REC_NoError) 
{ 
    // No error occurs while sending the command to the reader. Let's wait until the result handler was called. 
    if (ResultHandlerEvent.WaitOne(TimeSpan.FromSeconds(10))) 
    { 
     // The reader's work is done and the result handler was called. Let's check the result flag to make sure everything is ok. 
     if (_readerResultFlag == tKSRWResultFlag.KSRW_RF_NoError) 
     { 
      // The command was successfully processed by the reader. 
      // We'll display the result in the result handler. 
     } 
     else 
     { 
      // The command can't be proccessed by the reader. To know why check the result flag. 
      logger.error("Command \"KSRWSyncGetEPCs\" returns with error {0}", _readerResultFlag); 
     } 
    } 
    else 
    { 
     // We're getting no answer from the reader within 10 seconds. 
     logger.error("Command \"KSRWSyncGetEPCs\" timed out"); 
    } 
} 

[...] 

private static void ResultHandlerSyncGetEPCs(object sender, tKSRWResultFlag resultFlag, tKSRWExtendedResultFlag extendedResultFlag, tKSRWEPCListEntry[] epcList) 
{ 
    if (Reader == sender) 
    { 
     // Let's store the result flag in a global variable to get access from everywhere. 
     _readerResultFlag = resultFlag; 

     // Display all available epcs in the antenna field. 
     Console.ForegroundColor = ConsoleColor.White; 
     foreach (var resultListEntry in epcList) 
     { 
      handleTagEvent(resultListEntry); 
     } 

     // Let's set the event so that the calling process knows the command was processed by reader and the result is ready to get processed. 
     ResultHandlerEvent.Set(); 
    } 
} 

答えて

1

あなたはgcroot<> helper classに問題があります。そのDLLの中で誰も見ることのできないコードで使用されます。管理コードと相互運用するように設計されたC++コードで頻繁に使用されますが、gcroot <>は管理対象オブジェクトへの参照を格納します。クラスはGCHandle型を使用して参照を追加します。 GCHandle.ToIntPtr()メソッドは、C++コードが格納できるポインタを返します。失敗した操作は、GCHandle.FromIntPtr()で、オブジェクトへの参照を回復するためにC++コードで使用されます。

この例外を取得するための二つの基本的な説明があります。

  1. は、それが正確であることができます。あるAppDomainからDLL内のコードを初期化して別のAppDomainで使用すると、どのようなことが起こりますか? Readerクラスのオブジェクトが初期化されるスニペットからは明らかではないので、これが説明であることはゼロ以外のオッズである。 Readerクラスを使用するコードの近くに保管してください。

  2. 別のバグ、DLL内のC++コードに存在する可能性があります。管理されていないコードは、誤ってメモリを上書きする可能性のあるバグのようなポインタのバグに悩まされることがよくあります。 gcroot <>オブジェクトが格納されているフィールドでそれが起こるとしばらく間違ったことはありません。コードが再びオブジェクト参照を回復しようとするまで。この時点で、CLRは、破損したポインタ値が実際のオブジェクトハンドルと一致しなくなり、この例外を生成することに気付きます。これは確かに困難な種類のバグです。これはコード内で発生するので、修正することはできませんし、バグの修復が非常に困難なプログラマーを示すことができます。

最初にチェース箇条書き#1。 BizTalkが別のAppDomainでC#コードを実行することは間違いありません。 AppDomainが作成される前または実行されている間、DLLの読み込みが遅すぎることがあります。 SysInternalsのProcMonで見ることができるもの。 AppDomainを作成し、テストコードを実行する小さなテストプログラムを作成して、これを再現してください。それがクラッシュを再現するならば、RFIDベンダーにその問題を実証する非常に良い方法と、RFIDベンダーがそれを使用して修正を行うことを期待しているでしょう。

解決策を得るためにRFIDリーダーベンダと良好な関係を持つことは、非常に重要になるでしょう。それは問題ではありません。いつも他の場所で買い物をするのに適しています。

+0

まずはお返事ありがとうございます。実際には、私はdllからオブジェクトをinstanciatingに成功し、それを使用します。上記のコードでわかるように、タグを読み取るときにリーダーが送信するイベントにメソッド(ResultHandlerSyncGetEPCs)を接続します。イベントが来るのを待っている行のソースコードがクラッシュする...タイムアウトのために少なくとも10秒待たずに、すぐに「GCHandle ...を渡すことはできません」という例外がスローされます。 – hurtauda

+0

そして、この時点でアンテナ上のタグを読み取っているため、リーダーが正しく接続されていて、 'Reader.KSRWSyncGetEPCs();' というメソッドを受け取ることができます。 – hurtauda

+0

私は、問題の原因を診断するための特別な勧告をしました。これを追求したくない場合は、ベンダーに直接サポートを依頼してください。 –

関連する問題

 関連する問題