2017-12-06 3 views
3

다른 클래스의 한 클래스에서 시작한 작업을 취소하고 싶습니다. 다음은 두 클래스가 있고 다른 클래스에서 작업을 취소하려는 예제 프로그램입니다. 취소 토큰이 작동하지 않는 것 같습니다.다른 클래스의 작업 취소 방법

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

취소 토큰 나던에서작동하는 것 같다.

실패하는 이유는 당신이 다른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 앱을 디자인하기 때문입니다. 버튼 클릭 후 한 페이지에서 우리는 비동기 함수 (배경 작업을하는)를 호출하고 로딩 화면도 표시합니다. 로딩 화면에는 작업을 취소하는 버튼이 있습니다. 로드 중 화면은 하나의 기본보기 모델과 이전 화면과 다른보기 모델에 연결되어 있으며 이전 화면에서 시작된 비동기 작업을 취소하려고합니다. 각각의 뷰가 데이터 컨텍스트에 대한 뷰 모델 객체를 생성하므로 토큰을 param으로 전달할 수 없습니다. –

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(); 
     }