2017-12-06 3 views
3

あるクラスから開始したタスクを他のクラスから取り消したいと思います。以下は、私が2つのクラスを持ち、異なるクラスからタスクを取り消したい場合のサンプルプログラムです。キャンセルトークンが機能していないようです。別のクラスからタスクをキャンセルする方法

namespace threadingiwthcancel 
{ 
    class ThreadExample 
    { 
     public async Task PrintSomething(CancellationToken token) 
     { 
      int i = 0; 
      while (true) 
      { 
       if (token.IsCancellationRequested) 
       { 
        Console.WriteLine("Cancel requested"); 
        break; 
       } 
       await Task.Delay(TimeSpan.FromSeconds(1)); 
       Console.WriteLine(i); 
       i++; 
      } 

     } 
    } 
    class Cancel 
    { 
     public void cancelTask() 
     { 
      CancellationTokenSource source = new CancellationTokenSource(); 
      source.Cancel(); 
     } 
    } 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      CancellationTokenSource source = new CancellationTokenSource(); 
      CancellationToken token = source.Token; 
      callasyncmethod(token); 
      Thread.Sleep(TimeSpan.FromSeconds(2)); 
      Cancel c = new Cancel(); 
      c.cancelTask(); 
      Console.ReadLine(); 
     } 

     private static async void callasyncmethod(CancellationToken token) 
     { 
      ThreadExample te = new ThreadExample(); 
      await te.PrintSomething(token); 
     } 
    } 
} 
+0

:私はそれにソースを渡すようにしてくださいいくつかの他のクラスから

を一つのクラスによって開始されたタスクをキャンセルしたい

それがあなたのために働いたかどうか知っている –

答えて

2

キャンセルトークンのdoesntでは動作するように見えます。

失敗の理由は、あなたが異なるCancellationTokenSourceを作成し、その上にCancelを呼び出しているということです。残念ながら、他の操作は通知されないので、元のタスクは続行されます。私を聞かせて、答えを試してみる

class Cancel 
{ 
    CancellationTokenSource _source; 

    public Cancel (CancellationTokenSource source) 
    { 
     _source = source; 
    } 

    public void cancelTask() 
    {    
     _source.Cancel(); 
    } 
} 

    static void Main(string[] args) 
    { 
     CancellationTokenSource source = new CancellationTokenSource(); 
     CancellationToken token = source.Token; 
     callasyncmethod(token); 
     Thread.Sleep(TimeSpan.FromSeconds(2)); 
     Cancel c = new Cancel(source); // pass in the original source 
     c.cancelTask(); 
     Console.ReadLine(); 
    } 
+0

はいうまくいった。この投稿の理由は、それぞれがビューモデルを持つ複数のページを持つWPFアプリケーションを設計しているからです。ボタンをクリックした後のあるページでは、非同期関数(バックグラウンド作業を行う)を呼び出し、読み込み画面も表示します。ローディング画面には操作をキャンセルするボタンがあります。 Loading is画面は1ベースビューモデルと前の画面に別のビューモデルに関連付けられ、前の画面から開始された非同期操作をキャンセルしたいと考えています。各ビューはデータコンテキストのビューモデルオブジェクトを作成するため、トークンをパラメータとして渡すことはできません –

0

あなたはあなたにCancellationSoruceのオブジェクトを渡す必要があり、他のクラスのメソッドをキャンセルするよりも、新しいCancellationSoruceに作成していない、そのように行いたい場合で

class Cancel 
{  
public void cancelTask(CancellationTokenSource source) 
    { 
     source.Cancel(); 
    } 
} 

メイン

static void Main(string[] args) 
     { 
      CancellationTokenSource source = new CancellationTokenSource(); 
      CancellationToken token = source.Token; 
      callasyncmethod(token); 
      Thread.Sleep(TimeSpan.FromSeconds(2)); 
      Cancel c = new Cancel(); 
      c.cancelTask(source); 
      Console.ReadLine(); 
     } 

このようにするか

class Cancel 
    { 
     private readonly CancellationTokenSource source; 
     public Cancel(CancellationTokenSource source) 
     { 
      this.source = soruce; 
     } 
     public void cancelTask() 
     { 
      source.Cancel(); 
     } 
    } 

とメイン

static void Main(string[] args) 
     { 
      CancellationTokenSource source = new CancellationTokenSource(); 
      CancellationToken token = source.Token; 
      callasyncmethod(token); 
      Thread.Sleep(TimeSpan.FromSeconds(2)); 
      Cancel c = new Cancel(source); 
      c.cancelTask(); 
      Console.ReadLine(); 
     } 
関連する問題