163

スレッドで、いくつか作成してSystem.Threading.Task各タスクを開始します。

.Abort()スレッドを強制終了すると、タスクは中止されません。

.Abort()を自分のタスクに送信するにはどうすればよいですか?

4

12 に答える 12

241

できません。タスクは、スレッド プールのバックグラウンド スレッドを使用します。また、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();
    }
}
于 2011-01-24T15:44:52.837 に答える
35

タスクが実行されているスレッドをキャプチャすると、タスクを簡単に中止できます。これを示すコード例を次に示します。

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 クラスを使用してキャンセルする必要があるかどうかを判断しません。

于 2013-02-06T21:19:03.967 に答える
32

この投稿が示唆するように、これは次の方法で実行できます。

int Foo(CancellationToken token)
{
    Thread t = Thread.CurrentThread;
    using (token.Register(t.Abort))
    {
        // compute-bound work here
    }
}

機能しますが、このようなアプローチを使用することはお勧めしません。タスクで実行されるコードを制御できる場合は、キャンセルを適切に処理することをお勧めします。

于 2013-10-11T06:26:20.430 に答える
20

Abortこの種のことは、推奨されない論理的な理由の 1 つです。何よりもまず、可能な限り、スレッドのキャンセルまたは停止には使用しないでください。Thread.Abort() Abort()タイムリーに停止するためのより平和的な要求に応答していないスレッドを強制的に強制終了する場合にのみ使用してください。

そうは言っても、一方のスレッドが設定して待機している間、もう一方のスレッドが定期的にチェックして正常に終了する共有キャンセル インジケーターを提供する必要があります。.NET 4 には、この目的のために特別に設計された構造であるCancellationToken.

于 2011-01-24T15:48:23.393 に答える
9

Task.Factory.StartNew() で匿名メソッドを使用しない場合に CancellationToken を使用する方法に関する Prera​​k 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, 

}
于 2014-10-14T13:49:39.977 に答える
8

これを直接実行しようとしないでください。CancellationTokenで動作するようにタスクを設計し、この方法でキャンセルします。

さらに、CancellationToken を介して機能するようにメイン スレッドを変更することもお勧めします。電話Thread.Abort()をかけるのは悪い考えです。診断が非常に難しいさまざまな問題が発生する可能性があります。代わりに、そのスレッドは、タスクが使用するものと同じキャンセルを使用できます。同じものを使用して、すべてのタスクとメイン スレッドCancellationTokenSourceのキャンセルをトリガーできます。

これにより、はるかにシンプルで安全な設計が可能になります。

于 2011-01-24T15:46:53.200 に答える
4

タスクには、キャンセル トークンによるキャンセルのファースト クラス サポートがあります。キャンセル トークンを使用してタスクを作成し、これらを介して明示的にタスクをキャンセルします。

于 2011-01-24T15:44:54.740 に答える
4

を使用しCancellationTokenて、タスクをキャンセルするかどうかを制御できます。開始前に中断することについて話しているのですか (「気にしないでください、私はすでにこれを行いました」)、または実際に途中で中断することについて話しているのですか? 前者の場合、CancellationTokenが役立ちます。後者の場合は、おそらく独自の「救済」メカニズムを実装し、タスク実行の適切な時点ですぐに失敗するかどうかを確認する必要があります (CancellationToken を使用して支援することはできますが、もう少し手動です)。

MSDN には、タスクのキャンセルに関する記事があります: http://msdn.microsoft.com/en-us/library/dd997396.aspx

于 2011-01-24T15:45:30.363 に答える
3

タスクは ThreadPool で実行されているため (少なくとも、既定のファクトリを使用している場合)、スレッドを中止してもタスクには影響しません。タスクの中止については、msdnの「タスクのキャンセル」を参照してください。

于 2011-01-24T15:44:47.377 に答える