2017-03-04 6 views
0

DLL関数の1つをバックグラウンドスレッド内で呼び出しています。スレッド内のdll関数呼び出しを処理する方法#

問題は、アプリケーションが直接クラッシュするDLLが見つからない場合です。私もtry-catchで試しましたが、アプリケーションはクラッシュしますか?

メインUIスレッドでDLL関数を呼び出すと、アプリケーションで例外が処理されます。

バックグラウンドスレッド内で例外を処理するにはどうすればよいですか?ここ

mythread = new Thread(CM); 
mythread.IsBackground = true; 
mythread.Start(); 

private void CM() 
    { 
     // Perform a protection check with default options 
     try 
     { 
      ret_code = myclass.CheckProtection(myclass.CheckProtectionOptions.Default); 
     } 
     catch(Exception cm) 
     { 
      throw cm; 
     } 

}

+0

あなたが試したことを共有することができます –

+0

読み込んでいるDLLは何ですか –

+0

私のDLLをexeフォルダの場所にコピーしています – kaviarasan

答えて

1

クイック答え。

一部のDLLには、それを起動する最初のスレッドとの親和性があります。私が過去にしたことは、バックグラウンドでループを使ってスレッドを生かしておくことです。その後、そのDLLが読み込んだスレッドのイベントを待ち受けます。 DLLコールを呼び出すのではなく、イベントをリッスンするコードを少し変更する必要があるかもしれません。

希望しますか?

私はいくつかのサンプルコードを追加しました。これを試して、何が起こるかを見てください。それは完璧ではありませんが、スレッドを生かし続ける方法を説明するのに役立ちます。そこにこれを行うための他の方法がありますが、私はちょうど

using System; 
    using System.Reflection; 
    using System.Threading; 

    namespace ConsoleApplication3 
    { 
     internal class Program 
     { 
      private static void Main(string[] args) 
      { 
       var newThread = new Thread(DllLoader.DoWork); 
       newThread.Start(); 

       //My other application Logic 
      } 

      public class DllLoader 
      { 
       public enum ThingsICanDo 
       { 
        Jump, 
        Duck, 
        Run, 
        Quit 
       } 

       private static bool appStillRunning; 
       private static object myInstanceDllType; 

       private static void CheckForStuffToDo() 
       { 
        //Much better to use events, and pass the message inthe event 
        // then do what the message wants, and but I am keeping this breif 
        // for this example. 
        var DoNext = (ThingsICanDo) Enum.Parse(typeof (ThingsICanDo), Console.ReadLine(), true); 
        switch (DoNext) 
        { 
         case ThingsICanDo.Jump: 
          //Do jump stuff 
          Console.WriteLine("Jump"); 
          //myInstanceDllType.JumpStuff(); 
          break; 
         case ThingsICanDo.Duck: 
          Console.WriteLine("Duck"); 
          //myInstanceDllType.DuckStuff(); 
          //Do duck stuff 
          break; 
         case ThingsICanDo.Run: 
          Console.WriteLine("Run"); 
          //myInstanceDllType.RunStuff(); 
          //Do run stuff 
          break; 
         case ThingsICanDo.Quit: 
          //Do exit stuff 
          Console.WriteLine("Bye"); 
          Thread.CurrentThread.Abort(); 
          break; 
        } 
       } 

       public static void DoWork() 
       { 
        var externalAssembly = Assembly.LoadFrom("/path/my.Dll"); 
        myInstanceDllType = Activator.CreateInstance("DLLTypeINeed"); 
        while (appStillRunning) 
        { 
         try 
         { 
          CheckForStuffToDo(); 
         } 
         catch (Exception e) 
         { 
          //Log e 
          Console.WriteLine(e); 
         } 
         Thread.Sleep(1000); 
          //Much better to use semaphore.wait or something similar, but this is a simple example 
        } 
       } 
      } 
     } 
    } 
+0

意味があります。しかしplzはいくつかのサンプルコードを投稿できますか? – kaviarasan

+0

それはかなり複雑です、ビット私はチャンスを得るときにあなたのための例を準備しようとします –

+0

大福私は投げていない場合でも – kaviarasan

1

は「あなたが行うべきではありませんもの」のカテゴリーに属している簡単な例を維持したいです。デプロイメントエラーです。誰かにその修正を依頼するには、大きなメッセージが常に必要です。しかし、anyhoo、問題はtry/catchが間違って配置されていることです。ジャストインタイムコンパイラによって例外がスローされ、が実行を開始する前にマシンコードを生成しようとします。スレッドでこれを行うと、複雑になりますが、それを捕まえることができるのはCLRだけです。

あなたは、常に働くことに頼ることのできる小さなスタブ法を意図的に書く必要があります。そして、次に、危険なコードを呼び出さなければなりません。今では、必要なtry/catchを注入する方法があります。また、リリースビルドでこれが動作することを確認する必要があります。これは、ジッタを遅くして危険な方法をインライン展開することを防ぐ必要があります。それには属性が必要です。このように:

using System.Runtime.CompilerServices; 
... 
mythread = new Thread(CMStub); 
mythread.IsBackground = true; 
mythread.Start(); 
... 

void CMStub() { 
    try { 
     CM(); 
    } 
    catch (Exception ex) { 
     LogFatalError(ex); // Don't throw! 
    } 
} 

[MethodImpl(MethodImplOptions.Noinlining)] 
void CM() { 
    // risky code here 
} 

使用される元のコードは動作しません。ブレッドクラムを残す必要はありませんので、スレッドが実行していたことをスレッドが実行していないことを伝えることはできません。いくつかの種類のロガーまたはEventLogクラスは絶対最小要件です。

+0

ありがとうございます。それでも私のアプリケーションはクラッシュしますか? – kaviarasan

+0

LogFatalError()メソッドがあなたのアプリをクラッシュさせないように意図していましたが、あなたのアプリが誤動作している理由を誰かが知ることができるように単に報告するだけでした。コメントの曖昧さは、あなたがなぜこれをやってはいけないのかというさらなる理由を提供します。 –

+0

他にクラッシュを防ぐ方法はありませんか? – kaviarasan

関連する問題