2012-08-02 1 views
1

세 개의 버튼이있는 Windows 양식이 있습니다. 하나의 버튼은 BlockingCollection에 항목을 추가합니다. 하나는 목록 처리를 시작하고 다른 하나는 목록 처리를 중단합니다.취소 후 작업 시작 방법

BlockingCollection에 항목을 추가 할 수 있으며 시작을 클릭하면 예상대로 목록이 소비됩니다. 나는 여전히 새로운 아이템을 추가 할 수 있으며 계속해서 소비 될 것입니다. 그러나 중지 버튼을 클릭하면 작업이 중지되지 않지만 시작 버튼을 사용하여 다시 시작할 수 없습니다.

내가 작업을 취소 할 때 잘못한 것은 무엇입니까? 다시 시작할 수 없다는 것입니까? 나는 작업을 취소 할 때 무수한 항목을 읽었지만 여전히 그것을 얻지는 않습니다.

도움이 될 것입니다. 코드는 다음과 같습니다.

// Blocking list for thread safe queuing 
    private BlockingCollection<QueueItem> ItemList = new BlockingCollection<QueueItem>(); 
    private CancellationTokenSource CancelTokenSource = new CancellationTokenSource(); 
    private int MaxConsumers = 3; 

    // Form initialisation 
    public MainForm() 
    { 
     InitializeComponent(); 
    } 

    // Create an async consumer and add to managed list 
    private void CreateConsumer(int iIdentifier) 
    { 
     Task consumer = Task.Factory.StartNew(() => 
     { 
      foreach (QueueItem item in ItemList.GetConsumingEnumerable()) 
      { 
       Console.WriteLine("Consumer " + iIdentifier.ToString() + ": PROCESSED " + item.DataName); 
       Thread.Sleep(894); 

       if (CancelTokenSource.IsCancellationRequested) 
        break; // Cancel request 
      } 
     }, CancelTokenSource.Token); 
    } 

    // Add a new item to the queue 
    private void buttonAdd_Click(object sender, EventArgs e) 
    { 
     for (int i = 0; i < 10; i++) 
     { 
      Task.Factory.StartNew(() => 
      { 
       // Add an item 
       QueueItem newItem = new QueueItem(RandomString(12)); 

       // Add to blocking queue 
       ItemList.Add(newItem); 
      }); 
     } 
    } 

    // Start button clicked 
    private void buttonStart_Click(object sender, EventArgs e) 
    { 
     buttonStart.Enabled = false; 
     buttonStop.Enabled = true; 

     // Create consumers 
     for (int i = 0; i < MaxConsumers; i++) 
     { 
      CreateConsumer(i); 
     } 
    } 

    // Stop button clicked 
    private void buttonStop_Click(object sender, EventArgs e) 
    { 
     CancelTokenSource.Cancel(); 

     buttonStop.Enabled = false; 
     buttonStart.Enabled = true; 
    } 

    // Generate random number 
    private static Random random = new Random((int)DateTime.Now.Ticks); 
    private string RandomString(int size) 
    { 
     StringBuilder builder = new StringBuilder(); 
     char ch; 
     for (int i = 0; i < size; i++) 
     { 
      ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65))); 
      builder.Append(ch); 
     } 

     return builder.ToString(); 
    } 

답변

4

취소하도록 구성된 취소 토큰을 다시 사용합니다.

새 작업을 시작할 때 새 토큰을 만드십시오.

+0

답장을 보내 주셔서 감사합니다. 그러나 어느 단계에서해야합니까? 작업이 취소되었는지 또는 취소() 명령을 실행 한 후에도 중요하지 않은지 어떻게 알 수 있습니까? – Simon

+0

새 작업을 시작할 때 새 토큰을 만듭니다. 현재 토큰을 재설정하면 아직 취소되지 않은 작업에 영향을 미칩니다. –

+0

감사합니다 - 완벽하게 일했습니다. :) – Simon