AccessViolationExceptionを処理する方法
質問
.NETアプリケーション内からCOMオブジェクト(MODI)を使用しています。私が呼び出している方法は、System.AccessViolationExceptionをスローします。これはVisual Studioによって傍受されます。奇妙なことは、私がCallをTry Catchに巻き付けたことです。これにはAccessViolationException、Comexception、その他すべてのハンドラーがありますが、Visual Studio(2010)がAccessViolationExceptionを傍受すると、デバッガーがメソッドコール(doc.ocr)で破損します。そして、私がステップスルーすると、キャッチブロックに入る代わりに次の行まで続きます。さらに、これをVisual Studioの外で実行すると、アプリケーションがクラッシュします。 COMオブジェクト内にスローされるこの例外を処理するにはどうすればよいですか?
MODI.Document doc = new MODI.Document();
try
{
doc.Create(sFileName);
try
{
doc.OCR(MODI.MiLANGUAGES.miLANG_ENGLISH, false, false);
sText = doc.Images[0].Layout.Text;
}
catch (System.AccessViolationException ex)
{
//MODI seems to get access violations for some reason, but is still able to return the OCR text.
sText = doc.Images[0].Layout.Text;
}
catch (System.Runtime.InteropServices.COMException ex)
{
//if no text exists, the engine throws an exception.
sText = "";
}
catch
{
sText = "";
}
if (sText != null)
{
sText = sText.Trim();
}
}
finally
{
doc.Close(false);
//Cleanup routine, this is how we are able to delete files used by MODI.
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(doc);
doc = null;
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
}
解決
.NET 4.0では、ランタイムは、破損状態の指標として、Windows構造化エラー処理(SEH)エラーとして提起された特定の例外を処理します。これらの破損した状態の例外(CSE)は、標準の管理コードによってキャッチされることは許可されていません。私はなぜここにいるのか、どのようにここにいるのかについては触れません。 .NET 4.0フレームワークでCSEに関するこの記事を読む:
http://msdn.microsoft.com/en-us/magazine/dd419661.aspx#id0070035
しかし、希望があります。これを回避する方法はいくつかあります:
.NET 3.5アセンブリとして再コンパイルし、.NET 4.0で実行します。
構成/ランタイム要素の下にあるアプリケーションの構成ファイルに行を追加します。
<legacyCorruptedStateExceptionsPolicy enabled="true|false"/>
これらの例外をキャッチしたい方法を飾る
HandleProcessCorruptedStateExceptions
属性。見る http://msdn.microsoft.com/en-us/magazine/dd419661.aspx#id0070035 詳細については。
編集
以前は、aを参照しました フォーラム投稿 詳細については。しかし、Microsoft Connectが廃止されたため、興味のある場合の追加の詳細は次のとおりです。
MicrosoftCLRチームの開発者であるGaurav Khannaから
この動作は、破損した状態の例外と呼ばれるCLR 4.0の機能により、設計によるものです。簡単に言えば、管理されたコードは、破損したプロセス状態を示す例外をキャッチしようとするべきではなく、AVはその1つです。
その後、彼は続けて handleProcessCorruptedStateExceptionsAttribute そして上記の記事。言うだけで十分です、これらのタイプの例外をキャッチすることを検討しているなら、それは間違いなく読む価値があります。
他のヒント
構成ファイルに次のものを追加すると、Catchブロックをtryでキャッチします。注意の言葉...この状況を避けてみてください。これは、何らかの違反が起こっていることを意味するためです。
<configuration>
<runtime>
<legacyCorruptedStateExceptionsPolicy enabled="true" />
</runtime>
</configuration>
上記の回答から編集され、私のために働き、それをキャッチするための次の手順を実行しました。
ステップ#1-次のスニペットを構成ファイルに追加する
<configuration>
<runtime>
<legacyCorruptedStateExceptionsPolicy enabled="true" />
</runtime>
</configuration>
ステップ2
追加 -
[HandleProcessCorruptedStateExceptions]
[SecurityCritical]
関数の一番上であなたは例外をキャッチしています
ソース: http://www.gisremotesensing.com/2017/03/catch-exception-attempted to-read-or.html
使用してみてください appdomain.unhandledexception そして、それがあなたがそれを捕まえることができるかどうかを確認します。
**編集*
これがいくつかあります 詳しくは それは有用かもしれません(それは長い読み物です)。