2014-01-15 2 views
3

.net에서 비동기 프로그래밍에 대한 몇 가지 테스트를 시작하고 있습니다. 이제는 cancellationToken을 사용하여 긴 작업을 취소하려고 노력하고 있습니다.작업이 실행되는 동안 비동기 취소

그래서 나는 다음과 같은 코드를 가지고 :

private void button2_Click(object sender, EventArgs e) 
    { 
     cancelationToken.Cancel(true); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     StartOperation(cancelationToken.Token); 
    } 

그리고 마지막으로 내 작업

private async void StartOperation(CancellationToken cancelToken) 
    { 
     await GetItensFromDatabase2(cancelToken); 
    } 

    public static Task<int> GetItensFromDatabase(CancellationToken cancelToken) 
    { 
     //cancelToken.Register(() => Console.WriteLine("Canceled")); 
     return Task.Factory.StartNew<int>(() => 
     { 
      int result = 0; 

      cancelToken.ThrowIfCancellationRequested(); 

      result = MyLongOperation(); // Simulates my operation -> I want to cancel while this operation is still running 

      return result; 

     }, cancelToken); 
    } 

작업을 시작

CancellationTokenSource cancelationToken = new CancellationTokenSource(); 

내 버튼 그래서, MyLongOperation을 취소하는 방법() 방법? 할 수 있습니까?

+0

'async' 코드는'StartNew' 대신'Task.Run'을 사용하십시오; [왜 내 블로그에서 설명할까요?] (http://blog.stephencleary.com/2013/08/startnew-is-dangerous.html). –

+0

Task.Run이 .net 4에 존재하지 않습니다. – mmarques

+0

'Microsoft.Bcl.Async'에서, 그것은'TaskEx.Run'입니다. –

답변

5

어느 시점에서 취소 할 수 없습니다, CancellationToken의 목적은 장기 실행 작업이 예상 될 때 사용자가 작업을 취소 할 수 있도록하는 것입니다 ...

여기
while(!finished) 
{ 
    cancelToken.ThrowIfCancellationRequested(); 
    //Some not cancelable operations 
} 

이 더 일반적인 방법입니다 취소 가능한 방법

private static void LongRunning(CancellationToken cancelToken) 
{ 
    while (true) 
    { 
     if(cancelToken.IsCancellationRequested) 
     { 
      return; 
     } 
     //Not canceled, continue to work 
    } 
} 

아이디어는 사용자가 취소를 요청하지만 집행자 만 언제 작업을 중지할지 결정합니다. 일반적으로 집행자는 "안전 포인트"에 도달 한 후 취소 할 것입니다

Abort 오랫동안 운영하는 것은 오랫동안 운영하지 않고도 이에 대한 질문없이 많은 게시물이 작성되었습니다.

+0

당신이 말하는 것은 루프 내에서 작업 만 취소 할 수 있다는 것입니다. 현재 실행 지점이 if (cancelToken.IsCancellationRequested) 외부에 있고 사용자가 취소하기를 원한다면이 시점에서 취소가 허용되지 않습니까? – mmarques

+0

(cancelToken.IsCancellationRequested) return보다 루프 선형, 일부 코드를 실행할 수 있습니다. 다른 코드보다, 다시 취소 및 취소 확인 ... –

1

글쎄, "cancelToken.ThrowIfCancellationRequested"라는 논리를 이미 실행 한 다음 취소하면 문제가 발생할 수 있습니다. "MyLongOperation"이 작업을 취소했다는 것을 어떻게 알 수 있습니까? :)

코드가 같은 것을 보일 것이다, 그래서 오랫동안 실행중인 작업은 보통 인수로 CancellationToken에 걸리는 취소 :

// Check if cancelled 
// do work part 1 
// Check if cancelled 
// do work part 2 

취소 해 작업의 단위는 개발자 개까지입니다.

+0

그건 두려워 aproach이야. 감사 – mmarques

관련 문제