2013-05-04 6 views
0

.net 4.5의 스레딩 모델 (또는 일반적으로 스레딩)에 대해서는 아직 상당히 익숙합니다. 일련의 유사한 작업을 멀티 스레딩하기위한 프레임 워크를 구현하기 위해 추상 클래스 집합을 작성하려고합니다. 입력의 첫 번째 줄에는 집합에 몇 개의 문제가 있는지를 나타내는 규칙이 있으며, 다음 줄에는 각 문제의 입력이 들어 있습니다. 집합을 구성하는 입력 행의 수는 한 작업에서 다음 작업까지 다양 할 수 있지만 일반적으로 특정 유형의 문제에 대해 일관됩니다. 각 문제는 한 줄의 텍스트를 출력으로 갖는 것입니다.외부에서 작업 목록을 중단하는 방법

이 클래스의 목표는 CreateWorker 및 DoWork 메서드를 구현하는 것에 대해 걱정할 필요가있는 것입니다. UI는 ProcessInput을 호출하여 작업을 시작하고 WriteOutput은 결과를 나열합니다.

내가 지금까지 가지고있는 기본 템플릿은 다음과 같습니다

public abstract class Wrapper 
{ 
    protected int N; 
    protected WorkerBase[] ProblemSet; 
    protected List<Task> Tasks; 

    public virtual void ProcessInput(TextReader input) 
    { 
     string Line = input.ReadLine(); 
     N = int.Parse(Line); 
     ProblemSet = new WorkerBase[N]; 
     Tasks= new List<Task>(N); 
     for (int index = 0; index < N; index++) 
     { 
      WorkerBase T = CreateWorker(input); 
      Tasks.Add(T.DoWorkAsync()); 
      ProblemSet[index] = T; 
     } 
    } 

    public virtual bool WriteOutput(TextWriter outputStream, int timeout) 
    { 
     bool Complete = Task.WaitAll(Tasks.ToArray(), timeout); 

     for (int index = 0; index < N; index++) 
     { 
      outputStream.WriteLine(ProblemSet[index].Result); 
     } 

     return Complete; 
    } 

    protected abstract WorkerBase CreateWorker(TextReader inputStream); 
    protected abstract class WorkerBase 
    { 
     public string Result 
     { 
      get; 
      protected set; 
     } 
     protected abstract void DoWork(); 
     public Task DoWorkAsync() 
     { 
      return Task.Run(() => DoWork()); 
     } 
    } 
} 

은 그대로, 이쪽은 내 요구 사항을 충족한다. 하지만 이제 모든 스레드를 중지 할 수있는 Wrapper 클래스에 중단 기능을 추가하려고합니다. 그래서 질문은 취소 버튼을 클릭하면 내 UI가 프로세스를 중단 할 수있는 방식으로 중단 기능을이 구조로 어떻게 작동합니까? 가급적이면 DoWork 구현에 추가 코드를 작성할 필요가 없습니다.

작업을 중단하기 위해 취소 토큰에 전달되는 패턴을 찾았지만 발견 한 모든 버전은 DoWork가 토큰의 상태를 확인하고 자체를 중단해야합니다. 메소드 외부에서 DoWork를 중단시키는 방법을 정말로 원한다.

+0

스레드 대신 작업 목록을 호출해야합니다. 작업! = 스레드, 다른 개념.질문에 대해서는 CancelationTokenSource를 참조하십시오. http://msdn.microsoft.com/en-us/library/dd537607.aspx – jure

+0

컬렉션의 이름을 변경하고 이름을 변경했습니다. 이미 링크를 통해 읽었습니다. 대체 패턴이 필요했다. – Rozwel

답변

2

중단 코드 실행은 두 가지 방법으로 수행 할 수 있습니다 ("취소 할 작업에 대해 이미 발생하는 것으로 의심되는"작업 대기열에서 시작되지 않음 "을 포함하는 경우 3 가지가 있습니다). 제정신 :

  • 작업이 주기적으로 일부 플래그 "중단"확인하고
  • 당신이

첫 번째 전체 스레드를 당신이일을해야 무엇 중단 깨끗하게 자체를 종료; 대부분의 경우 잘 작동합니다. 두 번째는 사실상 결코 좋은 생각이 아닙니다. 당신이 이것을 고려해야 할 유일한 시간은 당신의 전체 과정이 너무 병약하여 당신이 단지 그것을 최대한 빨리 내려 놓고 (그리고 그것의 불행에서 벗어나고 싶을 때)입니다. 스레드를 중단 한 후에는 시스템을 복구 할 수없는 상태로 남겨 두었을 가능성이 높으므로 대부분의 정상적인 작업에는 절대로 사용해서는 안됩니다. 또한 : 여기에없는 Thread에 대한 참조가 필요합니다.

그래서 : 첫 번째 경우를 남깁니다. 솔직하게, 나는 당신이 단지 여기에서 깃발을 얻고, 점검해야한다라고 생각한다. 그러나 작업자가 어딘가에서 주기적으로 값을 가져와야하는 경우 을 잘 수행 할 수있는 또 다른 방법은 체크를 모든 입력 속성/메소드/등으로 설정하고 잘 알려진 예외, 즉 작업자를 발생시키는 것입니다 단지 foo.Count (또는 유사)에 액세스 할 때 예외가 발생할 수 있습니다.

이 공식적으로 취소 를 확인하고 작업의 상태가 유지 될 수 있도록,을 취소 한 것을보고 일반적으로, 그러나 바람직입니다. 그래도 catch 블록에서이 작업을 수행 할 수 있다고 생각합니다.

관련 문제