2011-10-27 3 views
21

.Net 4의 Task API를 사용하여 실행해야하는 백그라운드 스레드에 적합한 설계입니까? 내 유일한 관심사는 우리가 어떻게 할 것인지 그 일을 취소하고 싶다면 무엇입니까? 나는 단지 ProgramEndingtrue으로 설정할 수 있지만 작업 API에는 CancellationToken이 있다는 것을 알고 있습니다.모범 사례 LongRunning 작업 생성

이것은 하나의 스레드가 컬렉션에 추가되고 다른 스레드가 제거하려고하는 예제 코드 샘플입니다. 이 프로그램이 실행되는 동안 지속적으로 실행해야 같이 작업은 LongRunning로 설정되어

private void RemoveFromBlockingCollection() 
{ 
    while (!ProgramEnding) 
    { 
     foreach (var x in DataInQueue.GetConsumingEnumerable()) 
     { 
      Console.WriteLine("Task={0}, obj={1}, Thread={2}" 
          , Task.CurrentId, x + " Removed" 
          , Thread.CurrentThread.ManagedThreadId); 
     } 
    } 
} 

private void button1_Click(object sender, EventArgs e) 
{ 
    DataInQueue = new BlockingCollection<string>(); 
    var t9 = Task.Factory.StartNew(RemoveFromBlockingCollection 
           , TaskCreationOptions.LongRunning); 

    for (int i = 0; i < 100; i++) 
    { 
    DataInQueue.Add(i.ToString()); 
    Console.WriteLine("Task={0}, obj={1}, Thread={2}", 
         Task.CurrentId, i + " Added", 
         Thread.CurrentThread.ManagedThreadId); 
    Thread.Sleep(100); 
    } 
    ProgramEnding = true; 
} 

업데이트 : 난에 스레드를 가져 DataInQueue.CompleteAdding을 ProgramEnding 부울을 제거하고 사용할 수있는 것으로 나타났습니다 끝.

답변

18

이미 언급했듯이 CancellationToken을 사용할 수 있습니다. 이런 식 수행 취소가 요청 된 경우, 토큰을 요청할 수있는 장기 실행 작업에서는

cancellationTokenSource.Cancel(); 

:

var cancellationTokenSource = new CancellationTokenSource(); 
Task.Factory.StartNew(RemoveFromBlockingCollection 
         , TaskCreationOptions.LongRunning 
         , cancellationTokenSource.Token); 

그리고 나중에 코드에서를, 당신과 함께 작업을 취소 할 수 있습니다

if (cancellationTokenSource.Token.IsCancellationRequested) 
+0

스레드를 유지하는 것이 가장 좋은 방법이고 API 호출이 있습니까? BlockingCollection에서 CompleteAdding 메서드를 사용할 수 있지만 BlockingCollection을 사용하지 않고 다른 작업을 수행하면 부울이 accpetable이 될 수 있다는 것을 발견했습니다. – Jon

+0

예, 작동합니다. 또는 위에서 언급 한 CancellationToken을 사용합니다. – Fischermaen

+0

나는 스레드를 계속 실행하기 위해 귀하의 의견을 묻는 스레드를 취소하는 데 사용할 수 있습니까? – Jon