2017-06-15 26 views
0

私はC++コードベース(これは変更できません)で機能を呼び出すためにCLRを使用するC#アプリケーションを持っています。C#でC++スレッドでハンドル例外が発生しました

私のC#アプリはC++のものを初期化し、定期的にそれとやりとりします。

C++のものが初期化されると、スレッドが生成され、スレッドはアプリケーションの存続期間中実行されます。

私のコントロールを超えて、C++のものが例外を発生させる原因となる条件があります。これが私のアプリケーションをクラッシュさせています。私は、クラッシュの原因は私のアプリが何かによって開始されていないことを強調しなければならない**。

私はAppDomain.CurrentDomain.UnhandledExceptionルートを試しましたが、例外をキャッチしません。

アイデア?

**簡単に言えば、C++のスタッフがDirect3Dを起動します。デバイスが失われた場合、例外が発生します。これを引き起こす原因はいくつかありますが、ユーザーがPCをロックしている場合(Windows)などの良い例があります。

+3

この種のグルーロジックをしてください。それが基になるC++コードを呼び出し、管理されていない例外をキャッチして、それらを処理するか、またはマネージ例外として渡します。 – Rook

+0

処理されていない例外のためにC++スレッドが終了し、その上に管理スタックフレームがない場合、C++の問題は純粋です。そのスレッドと何らかの方法で対話できない場合、デフォルトのCRTアクションが呼び出され、アプリを終了します。このエラーを処理することができたとしても、部分的に作成されたC++オブジェクトに対処する必要があります。静的なものがあれば、適切に再初期化する方法はありません。ライブラリがそのようなことを処理する手段を提供していない場合、例えば、エラーを登録して、再起動が必要なハンドラを再試行してください。 –

+0

ありがとう@AloisKraus - 私は単純にCLRオブジェクトをインスタンス化して初期化できるので、エラーを処理することはできます。 – grae22

答えて

-2

外部コードを別のAppDomainで実行する必要があります。そのため、外部コードが失敗した場合でも、他のドメインが終了してもアプリケーションは実行され続けます。

public static class NewAppDomain 
{ 
    public static void Execute(Action action) 
    { 
     AppDomain domain = null; 

     try 
     { 
      domain = AppDomain.CreateDomain("New App Domain: " + Guid.NewGuid()); 

      var domainDelegate = (AppDomainDelegate)domain.CreateInstanceAndUnwrap(
       typeof(AppDomainDelegate).Assembly.FullName, 
       typeof(AppDomainDelegate).FullName); 

      domainDelegate.Execute(action); 
     } 
     finally 
     { 
      if (domain != null) 
       AppDomain.Unload(domain); 
     } 
    } 

    private class AppDomainDelegate : MarshalByRefObject 
    { 
     public void Execute(Action action) 
     { 
      action(); 
     } 
    } 
} 

その後、あなたはこのクラスここ

NewAppDomain.Execute(() => 
{ 
    //Here call external code 
    Console.WriteLine("Hello World"); 
}); 

詳細を使用して、新しいアプリケーションドメインで外部コードを実行することができます。https://malvinly.com/2012/04/08/executing-code-in-a-new-application-domain/

私がすることができますC++/CLIのラッパーアセンブリを作るために誘惑されると思います
+0

あなたは私のC++初期化呼び出しを "外部コード呼び出し"メソッドで行うべきだと言っていますか?そのメソッドが存在するときに結果オブジェクトが破棄されませんか? – grae22

+0

@ grae22この方法を使用すると、外部呼び出しに障害が発生してもアプリが実行され続けることを確認できます。あなたはあなたのアプリについて多くの詳細を述べていないので、あなたが外部関数を呼び出して返す必要があると仮定すると、これは行く方法です。あなたの外部オブジェクトを生かし続ける必要がある場合は、わずかに異なるアプローチが必要ですが、新しいAppDomainで確実に実行することは、アプリケーションを殺すような外部コードの処理に行く方法です。 – Oscar

+0

ありがとうございます@オスカー、私はあなたのソリューションを適応させて遊んでいます。 – grae22

関連する問題