2016-10-07 4 views
1

スレッドは割り込みをサポートしています。なぜタスクはありませんか?C#タスクが中断されているのはなぜですか?

私の(無知)の観点から、タスクが中断をサポートすることを可能にするのが妥当と思われる。)タスクが現在task.Interruptを(呼び出して、スレッド上で実行されていない場合は

  • をTaskInterruptExceptionを設定しますタスクがスケジュールされたときにスローされます。
  • それ以外の場合、タスクを実行しているスレッドでTaskInterrupExceptionがスローされます。この例外は、タスク内で捕捉されるか、または上部のAggregateExceptionに追加されます。この機能には、実行中のスレッドを知るタスクが必要になると思います(これは不合理ですか?)

この機能を実装するのに必要な部分は既に存在するのですか、それとも言語実装を変更する必要がありますか?

追加: 私はそれに関連する答えがCancellationTokenと(落胆)Thread.Abortアプローチを議論して、タスクを中止/殺害について議論SO上の数多くの質問を読みました。

私自身が手を出すと、CancellationToken.RegisterでThread.Interruptを登録しても、タスクで実行中のスレッドが中断されるのではなく、代わりにトークンのキャンセルを呼び出すスレッドが中断されることがわかりました。

私が見ているように、開発者がタスクを(静かに)終了できるようにするための認可された機能が必要です。

また、この機能は、開発者がではなく、がタスクで実行されているコードを所有している状況で特に有用であることを追加します(CancellationTokensを取るためにタスクを書き直さないようにする)。

そして、原則として、タスクの実行者が、タスクの実装者に応じて正しくキャンセルすることなく、キャンセルの保証を提供できる方法があるようです。キャンセルトークン。

別加え: かかわらず、リスクの、C#のAPIはThread.AbortThread.Interruptをサポートしています。だから、私の質問は、本質的には、同じAPI(同じ固有のリスクを持つ)をTaskがサポートしないのはなぜですか?

更新
この投稿はthis questionの重複としてマークされています。しかし、私は既にこの質問(とすべての回答)を投稿する前に、参照された質問を読んでいました。この質問は重複ではなく、追加の情報を求めている関連する質問です。その質問は「中止できますか?」と答え、本質的に「あなたは中止してはいけません」と質問します。「私の質問は、割り込みが中止よりも優れているから、なぜサポートされている機能を中断しないのですか? this questionによれば、を中断する重要な違いがあり、が中断してスレッドを中断し、その中断がより好ましい。

+3

http://stackoverflow.com/a/14831590/17034 –

+0

リンクありがとう、Hans。あなたはThread.Abortについて議論します。 Thread.Interruptについても同じですか?私は、Thread.Interruptが厄介な場所に例外を投げるのを避けることになっていたことを理解しました。 –

+0

また、リスクに関係なく、APIは引き続きThread.AbortとThread.Interruptをサポートしています。私の質問はなぜタスクは同じをサポートしていないのですか? –

答えて

1

そして、原則として、タスクの実行者が、タスクを正しく行うためのタスクの実装者に依存するのではなく、取り消しの保証を提供できる方法があるようですキャンセルトークンで

私はその陳述に同意しません。どんなに難しいことでも、あなたが所有していないコードを実行しているタスクを中止しようとしている場合は、システムを未定義の状態にして、正常に機能し続けることができません。

このように、このような状況を回避するには、タスクの優雅なキャンセルが唯一の方法です。 Taskを取り消す能力を持たない場合、リソースをリークして予期せずクラッシュしたり、余分なリソースや時間を無駄にするような、稼働中のシステム(24時間稼働するように設計されています) CacnellationToken

これは私の個人的な意見であり、ほとんどの場合有用であるよりもむしろ有害であるTask.Abort()が見つかりました。

EDIT:それはスレッドを追跡することはできませんのでまた、Taskは操作にちょうどハンドルがある、あなたは、TaskCompletionSource<T>を作成し、任意のスレッド上の任意の時点で完了を設定することができます(複数可)その背後にある論理コードTaskは実際に実行されています。たとえば、Task.WhenAll(Task[])Taskを返します。どうやって中止しますか?どのスレッドでも実行されていませんが、代わりに指定されたタスクの完了を待ち受けます。私。一般的なAbortメソッドを追加することは技術的に実現可能ではありません。

+0

Serge、編集を追加してうれしく思います。これは私がこの質問で探していた種類の情報です。 "タスクとタスクハンドルをサポートしている実際のコードが接続されていない可能性があり、タスクによって割り込みが必要なコードを特定できなくなる可能性があります。 –

+0

私は24時間365日の実行を意図したコードは決してスレッドを中止したくないことを理解しています。しかし、私のユースケースは、毎時ペイ・パー・ベースで実行される計算パイプラインです。何かがうまくいかない場合は、できるだけ早くすべてをダウンさせたいので(ユーザーが余分な費用を負担しないように)、エラーの原因をできるだけ正確にカタログします(パイプラインで問題を修正できるように)。 –

+0

いくつかのラッパー、 'Thread.Abort()'、 'Thread.ResetAbort()'を使って強制的に 'Task'を強制終了することは技術的に可能でなければなりません。どのようにして正確に行うかについて、別の質問を追加することができます。これは、特定のケースで問題を解決する唯一の最も簡単な方法です。 –

関連する問題