2016-04-07 19 views
4

私たちは、エンドユーザーによって不適切に設定されたときにハングアップする可能性のあるサードパーティメソッドを呼び出すWindowsサービスを用意しています。これは、事前にテストするのが難しいものです。ハングしたタスクをキャンセルするにはどうすればよいですか?

private int? FooWithTimeout() 
{ 
    var timeout = TimeSpan.FromMinutes(1); 
    var task = Task.Run(Foo); 

    if (!task.Wait(timeout)) 
    { 
     Log("Foo timed out..."); 
     return null; 
    } 

    if (task.IsFaulted) 
    { 
     Log("Foo threw an exception..."); 
     return null; 
    } 

    return task.Result; 
} 

サードパーティのメソッドブロック永遠に応答することはできませんリソースからの入力を待っている:私たちは、タイムアウトして、タスクのメソッドを呼び出すことで、このリスクを処理しています。 ではなく、は、いかなる形でもキャンセル、形状、フォームをサポートしていませんし、タイムアウトも組み込まれていません。私たちの懸念事項は、サービスの実行中にこれらのタスクがブロックされ、ゆっくりと蓄積され、最終的に大量のリソースを消費することです。

これは有効な問題ですか?タスクを何らかの方法で中止または処分する必要がありますか?もしそうなら、正しい方法は何ですか?

補足:第三者がCrystal Reportsです。ユーザーからの何らかの追加入力が必要なプリンタへの印刷を要求されたときにハングアップします(たとえば、Microsoft XPS Document Writerは、印刷するとファイルを保存する場所を尋ねます)。また、ハングアップすると、ユーザー入力のプロンプトを表示しようとしますが、Windowsサービスに入っているので、誰もプロンプトが表示されず、人間が印刷方法を永遠に待っています。エンドユーザーは、サービスが印刷しようとするプリンタを構成することができます。実際には、特定のプリンタで印刷しようとすると入力が不足する場合があります。

+0

「Foo」とは何ですか?スレッドをブロックする通常の方法?これは、タスクを中止する必要がある場合に役立ちます:http://stackoverflow.com/a/19311606/1657476 –

+3

あなたの質問は、基本的には「私は実装が不十分で、ランダムにサードパーティのソフトウェアを使用しています。 "問題は最初に*しないで解決しなければならないと私には思われます。あなたのサードパーティが問題を解決するのに悪い仕事をしている場合は、その貧しいデザインを修正するか、代替案を見つけるようにしてください。スレッドを強制終了するなどの危険な回避策は、プロセスの遅すぎる問題を解決するように思えます。 –

+0

ああ - 共通!私はいくつかのUIプロンプトを表示dllの多くを行っている。もちろん、それは最終的に修正する必要がありますが、私はいつも正しい解決を行う時間がありません。その後、レジストリのハッキング、一時ファイル、バッチなどすべてが行き渡ります。これは「不十分な設計」ではなく、修正が必要なバグです。アプリケーションが複雑な場合、すべてのUIプロンプトの発生位置を特定することは困難です。 – TarmoPikaro

答えて

3

私たちの関心は、サービスの実行時にこれらのタスクをブロックし続け、ゆっくりと

これが有効な関心事である蓄積することです。小さなスタックを使用する特別なスレッドプールでこれらのタスクを開始することで、その結果を減らすことができます。そうすれば、メモリ使用量は少なくなります。しかし、それは完全な修正ではありません。あなたが長い時間(何時間も使用することを意図したGUIアプリケーションではない)アプリケーションを機能させる必要がある場合、最終的にアプリケーションがリソースを使い果たしてしまうため、この解決策は容認できないものとなります。

.NETは、非協力スレッドを終了する方法がありません。これらのアクションは、それぞれのプロセスで実行する必要があります。これらのプロセスを安全に終了することができます。

AppDomainsの使用も安全ですが、あまり確実ではありません。 AppDomainとその中のスレッドがアボートされると、プロセスごとの状態が壊れている可能性があります。また、すべてのスレッドを中止することはできません。特にIO操作。

別々のプロセスを使用しても、終了によって状態の破損が発生しないことを保証するものではありません。しかし、実際には、ほとんどの壊れやすい状態がメモリにあります。プロセスの終了により、すべての不一致状態がクリアされる可能性があります。

+0

iisにも使われているthread.abortがあります。そして、私は数週間または数ヶ月間実行されます。 – riki

+1

IISは、明確に定義されたポイントの* current *スレッドに対してのみThread.Abortを使用します。 Thread.Abortは「悪」と呼ばれ、使用することはできません。 – usr

関連する問題