2015-01-27 3 views
1

주기적으로 실행해야하는 작업이 있습니다. 같은 나의 첫번째 구현되었다 ContinueWith를 사용하는 자체 계속 작업

CancellationTokenSource tokenSource = new CancellationTokenSource(); 
Task task = null; 
task = new Task((x)=> { 
    CheckTask(tokenSource); 
    //CheckTask2(t, (object)tokenSource); 
}, tokenSource.Token); 
task.Start(); 

가 그럼 난 왜 ContinueWith를 사용하여 일정을 변경하지 않고 작업에 루핑 생각 :

public static void CheckTask(CancellationTokenSource tokenSource) 
{ 
    do 
    { 
     // Do some processing 
     Console.WriteLine("Processing"); 

     // Sleep awhile and wait for cancellation 
     // If not cancelled, repeat 
    } while (!tokenSource.Token.WaitHandle.WaitOne(1500)); 

    Console.WriteLine("Bye bye"); 
} 

이 작업과 같이 시작된다? 나의 다음 구현은 다음과 같았다 :

public static void CheckTask2(Task task, object objParam) 
{ 
    CancellationTokenSource tokenSource = (CancellationTokenSource)objParam; 
    // Do some processing 
    Console.WriteLine("Processing"); 
    // Sleep awhile and wait for cancellation 
    if(tokenSource.Token.WaitHandle.WaitOne(1500)) 
    { 
     Console.WriteLine("Cancel requested"); 
     return; 
    } 
    // Reschedule 
    task.ContinueWith(CheckTask2, tokenSource); 
} 

두 번째 구현은 읽기 및 쓰기와 나의 테스트는 차이를 보이지 않았다 훨씬 쉽게하지만, 자신을 ContinueWith하는 작업에 대한 단점이 있다면 난 여전히 궁금해?

+0

이 질문은 http://programmers.stackexchange.com에 더 적합하다고 생각합니다. 즉, 그것은 받아 들여진 패턴처럼 보입니다 ([msdn에 대한이 질문] (https://social.msdn.microsoft.com/Forums/en-US/d3f4f460-7d35-4406-b427-9c77bbbe6b55/repeating-tasks 참조). ? forum = tpldataflow)); await와 async를 사용한 취소 패턴은 [이 질문과 답변] (http://stackoverflow.com/questions/18999827/a-pattern-for-self-cancelling-and-restarting-task)을 참고하십시오. 관련성이 없음 : p – Kilazur

+0

작업을 생성하는 데 관련된 시작 비용이 있지만 (ContinueWith가 수행 중임) 무시할 수 있어야합니다. 그것이 당신을 위해 작동하고 코드 클리너를 만드는 경우 : 계속하십시오. – Jcl

답변

5

계속 작업에 단점이 있는지 궁금합니다. 계속 하시겠습니까? ?

솔직히 말씀 드리면, 내가 첨부 한 연속 코드를 사용하면 코드의 읽기가 쉽지 않습니다. 이 속성에 액세스하는 것은 WaitHandle이 인스턴스화되도록

: 내가 볼 수있는 유일한 단점은 dispose your CancellationToken object에 지금 강제 토큰에 WaitHandle를 사용하는 것이 사실이다. 필요한 경우에만이 속성을 사용하는 것이 더 바람직하고 에 연결된 CancellationTokenSource 인스턴스를 처분하는 것이 가장 좋은 기회입니다 (소스를 처분하면 할당 핸들 처리). 핸들을 닫거나 폐기하지 마십시오. .

public static async Task CheckTask(CancellationToken token) 
{ 
    do 
    { 
     // Do some processing 
     Console.WriteLine("Processing"); 

     await Task.Delay(1500, token); 
    } while (!token.IsCancellationRequested); 

    Console.WriteLine("Bye bye"); 
} 

그리고 당신은 당신의 Task을 중지 할 때 다음 CancellationTokenSource를 통해 자사의 취소

대신, 좀 더 깨끗하고 읽을 수 Task.Delay와 패턴을 찾을 수 있습니다.

관련 문제