2012-08-02 72 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

感謝您的回覆。但是,我應該在什麼階段這樣做?我如何知道任務已被取消 - 或者在發出Cancel()命令後無關緊要? – Simon 2012-08-02 09:35:32

+0

開始新任務時創建一個新的令牌。重置當前令牌將影響尚未取消的任務。 – 2012-08-02 09:37:29

+0

謝謝 - 工作完美。 :) – Simon 2012-08-02 09:43:44

相關問題