(グローバル) 静的 IntPtr 変数が ap/invoke DLL 相互運用呼び出しに渡され、USB デバイスへの有効なハンドルが通常のコードでその変数に配置されます。
private static IntPtr commHandle = (IntPtr)0;
USB デバイスがハングしたり、異常な状態になったりすると、相互運用コードへの呼び出しは応答を無限に待ちます。アプリケーションのハングを回避するために、コードを通常のメソッド内の匿名メソッド スレッド (以下) に配置しました。ポートを開く呼び出しは機能しますが、返されたハンドルを使用するとエラーが発生します。これは、同じ種類のエラーです。そもそもポートが開かれていないかどうかを取得します。
public IntPtr OpenPort(int deviceID)
Thread weAreAnonymous = new Thread(() =>
{
if( 0==(int)commHandle)
{
var res = dllCommOpen(deviceID, out commHandle);
}
if ((int)res > 0)
{
dllComFlush(res);
this.IsOpen = ((int)res != 0);
}
});
weAreAnonymous.Start();
次に、スレッドがポートを開くのを少し待ちます。短い仮眠の後もスレッドがまだ実行されている場合は、ポートのオープンに失敗したことがわかり、それに応じて処理できます...ただし、返されたハンドルは有効であるように見えますが、実際には開いているポートを指していないようです!