2017-09-27 9 views
0

私たちのプログラムはDLLから未知のメソッドを実行しています。これらのメソッドはタイムアウトを処理せず、決して値を返さないことがあります。タイムアウト後にスタックメソッドを中止する

このように、私たちのMethodinfo.invoke(...)はこの行に永久に詰め込まれます。

私たちの方法を中止する方法はありますか? 私はおそらくこのメソッドを非同期的に実行する必要があることを理解していますが、これは問題ありません。私は、ファイルハンドルのようなものがDLL内に割り当てられている場合ThreadAbortExceptionでは動作しないようにしようとのコメントで示唆したように

​​
+0

'ThreadAbortException'? [mcve]を入力してください。 – dymanoid

+0

['CancellationTokenSource'](https://msdn.microsoft.com/en-us/library/system.threading.cancellationtokensource(v = vs.110).aspx)の詳細を参照してください。 – Shreevardhan

+0

CancellationTokenSourceがメソッドを1行で停止していると主張していますか? – humudu

答えて

3

ここで要求されるように可視化のためのいくつかの小さな例です。

しかし、ここであなたが行く:

public void BlockingCallWithTimeout() 
    { 
     Semaphore waitHandle = new Semaphore(0,1); 
     Thread thread = new Thread(this.Wrapper); 
     Timer timer = new Timer(state => 
     { 
      thread.Abort(); 
      waitHandle.Release(); 
     },null,5000,0); 

     thread.Start(waitHandle); 

     waitHandle.WaitOne(); //wait until completion or until timeout 
     timer.Dispose(); 
    } 

    public void Wrapper(object state) 
    { 
     Semaphore semaphore = (Semaphore)state; 

     //Call DLL Method 

     semaphore.Release(); 
    } 

あなたは(それを試していなかった)どこかのコードでThreadAbortExceptionのを処理する必要があります。このコードは単なる例です!タイムアウトと成功が同時に発生するケースを処理する必要があります。タイマーは実行中に処分されません。また、より多くの競争状態が発生する可能性があります。

+0

メソッドが文字列を返すためにいくつかの困難を与え、いくつかのオブジェクトと変数をパラメータとして受け入れる必要がありました。解決策は動作しますが、スレッドを中止すると問題が発生する可能性がありますが、少なくとも今は自分のプログラムではなく、悪いDLLであることをユーザーに伝えることができます。ありがとう – humudu

+0

更新:メソッドがCOMポートのようなリソースを使用していて、スレッドを中止すると、「安全なハンドルが閉じられました」というエラーが発生し、プログラムがクラッシュします。 しかし、私は別のappdomainの中で実行スレッドを持つことでそれを回避することもできました。 https://stackoverflow.com/questions/46562227/safe-handle-has-been-closed-thread-abort-can-program-crash-be-avoided – humudu

関連する問題