32

タスクアクションの実行中CancellationTokenにコンストラクターに渡されたものを取得できますか?Taskほとんどのサンプルは次のようになります。

CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = cts.Token;

Task myTask = Task.Factory.StartNew(() =>
{
    for (...)
    {
        token.ThrowIfCancellationRequested();

        // Body of for loop.
    }
}, token);

しかし、私のアクションがラムダではなく、他のクラスに配置されたメソッドであり、直接アクセスできない場合はどうなりtokenますか?token状態として渡すことが唯一の方法ですか?

4

7 に答える 7

14

しかし、私のアクションがラムダではなく、他のクラスに配置されたメソッドであり、トークンに直接アクセスできない場合はどうなりますか?トークンを状態として渡すのが唯一の方法ですか?

はい、その場合、状態としてボックス化されたトークンを渡すか、状態として使用する他のタイプに含める必要があります。

CancellationTokenただし、これは、メソッド内で使用する場合にのみ必要です。たとえば、を呼び出す必要がある場合token.ThrowIfCancellationRequested()

メソッドがスケジュールされないようにするためにトークンのみを使用している場合、それは必須ではありません。

于 2013-03-15T18:04:47.980 に答える
11

タスクアクションの実行中にタスクコンストラクターに渡されたCancellationTokenを取得できますか?

Taskいいえ、オブジェクトから直接取得することはできません。

しかし、私のアクションがラムダではなく、他のクラスに配置されたメソッドであり、トークンに直接アクセスできない場合はどうなりますか?トークンを状態として渡すのが唯一の方法ですか?

はい、これらは2つのオプションです。他にもあります。(おそらく包括的なリストではありません。)

  1. 匿名の方法でキャンセルトークンを閉じることができます

  2. あなたはそれを状態として渡すことができます

  3. タスクのデリゲートに使用されるインスタンスに、キャンセルトークンを保持するインスタンスフィールド、またはトークンを保持するオブジェクトなどを保持するインスタンスフィールドがあることを確認できます。

  4. トークンは、他のより大きなスコープを介して、状態として、つまりパブリック静的フィールドとして公開できます(ほとんどの場合、悪い習慣ですが、場合によっては適用される可能性があります)

于 2013-03-15T18:06:01.213 に答える
3

非常に簡単な解決策があります:

    class CancelingTasks
{
    private static void Foo(CancellationToken token)
    {
        while (true)
        {
            token.ThrowIfCancellationRequested();

            Thread.Sleep(100);
            Console.Write(".");                
        }
    }

    static void Main(string[] args)
    {
        CancellationTokenSource source = new CancellationTokenSource();
        CancellationToken tok = source.Token;

        tok.Register(() =>
        {
            Console.WriteLine("Cancelled.");
        });

        Task t = new Task(() =>
        {
            Foo(tok);
        }, tok);

        t.Start();

        Console.ReadKey();
        source.Cancel();
        source.Dispose();

        Console.WriteLine("Main program done, press any key.");
        Console.ReadKey();
    }
}
于 2016-12-23T16:46:20.750 に答える