スレッドで、いくつか作成してSystem.Threading.Task
各タスクを開始します。
.Abort()
スレッドを強制終了すると、タスクは中止されません。
.Abort()
を自分のタスクに送信するにはどうすればよいですか?
スレッドで、いくつか作成してSystem.Threading.Task
各タスクを開始します。
.Abort()
スレッドを強制終了すると、タスクは中止されません。
.Abort()
を自分のタスクに送信するにはどうすればよいですか?
できません。タスクは、スレッド プールのバックグラウンド スレッドを使用します。また、Abort メソッドを使用してスレッドをキャンセルすることもお勧めしません。キャンセル トークンを使用してタスクをキャンセルする適切な方法を説明している次のブログ投稿をご覧ください。次に例を示します。
class Program
{
static void Main()
{
var ts = new CancellationTokenSource();
CancellationToken ct = ts.Token;
Task.Factory.StartNew(() =>
{
while (true)
{
// do some heavy work here
Thread.Sleep(100);
if (ct.IsCancellationRequested)
{
// another thread decided to cancel
Console.WriteLine("task canceled");
break;
}
}
}, ct);
// Simulate waiting 3s for the task to complete
Thread.Sleep(3000);
// Can't wait anymore => cancel this task
ts.Cancel();
Console.ReadLine();
}
}
タスクが実行されているスレッドをキャプチャすると、タスクを簡単に中止できます。これを示すコード例を次に示します。
void Main()
{
Thread thread = null;
Task t = Task.Run(() =>
{
//Capture the thread
thread = Thread.CurrentThread;
//Simulate work (usually from 3rd party code)
Thread.Sleep(1000);
//If you comment out thread.Abort(), then this will be displayed
Console.WriteLine("Task finished!");
});
//This is needed in the example to avoid thread being still NULL
Thread.Sleep(10);
//Cancel the task by aborting the thread
thread.Abort();
}
Task.Run() を使用して、この最も一般的な使用例を示しました。古いシングル スレッド コードでタスクの快適さを使用します。これは、CancellationTokenSource クラスを使用してキャンセルする必要があるかどうかを判断しません。
この投稿が示唆するように、これは次の方法で実行できます。
int Foo(CancellationToken token)
{
Thread t = Thread.CurrentThread;
using (token.Register(t.Abort))
{
// compute-bound work here
}
}
機能しますが、このようなアプローチを使用することはお勧めしません。タスクで実行されるコードを制御できる場合は、キャンセルを適切に処理することをお勧めします。
Abort
この種のことは、推奨されない論理的な理由の 1 つです。何よりもまず、可能な限り、スレッドのキャンセルまたは停止には使用しないでください。Thread.Abort()
Abort()
タイムリーに停止するためのより平和的な要求に応答していないスレッドを強制的に強制終了する場合にのみ使用してください。
そうは言っても、一方のスレッドが設定して待機している間、もう一方のスレッドが定期的にチェックして正常に終了する共有キャンセル インジケーターを提供する必要があります。.NET 4 には、この目的のために特別に設計された構造であるCancellationToken
.
Task.Factory.StartNew() で匿名メソッドを使用しない場合に CancellationToken を使用する方法に関する Prerak K の質問に答えるには、MSDN の例に示すように、StartNew() で開始するメソッドに CancellationToken をパラメーターとして渡します。ここに。
例えば
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
Task.Factory.StartNew( () => DoSomeWork(1, token), token);
static void DoSomeWork(int taskNum, CancellationToken ct)
{
// Do work here, checking and acting on ct.IsCancellationRequested where applicable,
}
これを直接実行しようとしないでください。CancellationTokenで動作するようにタスクを設計し、この方法でキャンセルします。
さらに、CancellationToken を介して機能するようにメイン スレッドを変更することもお勧めします。電話Thread.Abort()
をかけるのは悪い考えです。診断が非常に難しいさまざまな問題が発生する可能性があります。代わりに、そのスレッドは、タスクが使用するものと同じキャンセルを使用できます。同じものを使用して、すべてのタスクとメイン スレッドCancellationTokenSource
のキャンセルをトリガーできます。
これにより、はるかにシンプルで安全な設計が可能になります。
タスクには、キャンセル トークンによるキャンセルのファースト クラス サポートがあります。キャンセル トークンを使用してタスクを作成し、これらを介して明示的にタスクをキャンセルします。
を使用しCancellationToken
て、タスクをキャンセルするかどうかを制御できます。開始前に中断することについて話しているのですか (「気にしないでください、私はすでにこれを行いました」)、または実際に途中で中断することについて話しているのですか? 前者の場合、CancellationToken
が役立ちます。後者の場合は、おそらく独自の「救済」メカニズムを実装し、タスク実行の適切な時点ですぐに失敗するかどうかを確認する必要があります (CancellationToken を使用して支援することはできますが、もう少し手動です)。
MSDN には、タスクのキャンセルに関する記事があります: http://msdn.microsoft.com/en-us/library/dd997396.aspx
タスクは ThreadPool で実行されているため (少なくとも、既定のファクトリを使用している場合)、スレッドを中止してもタスクには影響しません。タスクの中止については、msdnの「タスクのキャンセル」を参照してください。