2015-09-03 67 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吗? –

相关问题