2015-09-03 140 views
1

我已經閱讀了一些關於此的文章,但我目前沒有任何明智之舉。我正在製作一個TabControl位於窗體上的應用程序。當用戶點擊標籤頁時,我希望後臺進程從UI線程運行(因爲該過程可能需要幾分鐘)。這很好,但是如果用戶選擇不同的選項卡,我想要取消任何當前活動的任務,並且要注意轉到新選項卡。取消並重新啓動任務

private void ParentTabControl_SelectedIndexChanged(object sender, EventArgs e) 
    { 
     Task testTask; 
     CancellationTokenSource testSource = new CancellationTokenSource(); 
     CancellationToken testToken = testSource.Token; 

     switch (ParentTabControl.SelectedIndex) 
     { 
      case 0: 
       updateSummaryTab(); 
       break; 
      case 1: 
       testTask = Task.Run(() => 
        { 
         updateTabOne(); 
        }, testToken); 
       break; 
      case 2: 
       updateTabTwo(); 
       break; 
     } 
    } 

如果我設置testSource取消,那麼這將不再使用(雖然我知道我將需要使用某種形式的令牌)。我之前爲每個選項卡使用了不同的BackgroundWorker,並簡單地檢查了它的IsBusy屬性,但我認爲使用單個回收的任務可能是更好的選擇。

+0

你有什麼具體問題?似乎所有你需要做的是取消任何傑出的工作,當標籤切換並開始新的工作。 – usr

+0

我得到的問題是當我使用CancellationToken取消任務時,新任務無法啓動(可能是因爲它使用相同的標記,現在設置爲取消) –

回答

1

我得到的問題是,當我取消使用的CancellationToken任務,新任務無法啓動

工作的每一輪,你開始創建一個新的CTS(和CT)。您需要將最後一輪的CTS存儲在一個字段中。然後,開始新的工作是:

if(cts != null) cts.Cancel(); 
cts = new ...; 
StartWork(cts.Token); 

要知道,取消正在運行的任務是合作和傳遞令牌Task.Run什麼也不做,因爲它不會停止已經運行的任務。

+0

我有一種感覺,我必須回收CancellationTokenSource ,我無法理解我的方式。如果將令牌傳遞給任務不會在任務運行時取消它(但使用cts.Cancel()),那麼使用令牌有什麼意義? –

+0

您需要將令牌傳遞給「StartWork」並在那裏使用它。輪詢它或將它傳遞給IO方法。 – usr

+0

啊,似乎運行任務不能被取消。你會推薦我回到在這種情況下使用BackgroundWorker嗎? –

相關問題