我有一个耗时的任务,我需要在一个单独的线程中运行,以避免锁定GUI线程。随着此任务的进行,它会更新特定的GUI控件。
问题是用户可能在任务结束之前移动到GUI的另一部分,在这种情况下,我必须:
对于一个具体的例子,假设表单有两个部分:一个用于导航目录树,另一个用于显示缩略图。当用户导航到另一个目录时,需要刷新缩略图。
首先我想到使用BackgroundWorker
和AutoResetEvent
等待取消,但我必须弄乱一些东西,因为我在取消时遇到了僵局。然后我读到了TPL,它应该取代BGW和更原始的机制。
使用TPL可以轻松完成吗?
答案 0 :(得分:22)
有几点需要注意:
您可以从CancellationToken
CancellationTokenSource
任务取消是合作操作:如果您的任务未定期检查CancellationToken.IsCancellationRequested
属性,则尝试取消任务的次数无关紧要,它会愉快地流失。
那些事情说,这是一般的想法:
void Main()
{
var tokenSource = new CancellationTokenSource();
var myTask = Task.Factory
.StartNew(() => DoWork(tokenSource.Token), tokenSource.Token);
Thread.Sleep(1000);
// ok, let's cancel it (well, let's "request it be cancelled")
tokenSource.Cancel();
// wait for the task to "finish"
myTask.Wait();
}
public void DoWork(CancellationToken token)
{
while(!token.IsCancellationRequested)
{
// Do useful stuff here
Console.WriteLine("Working!");
Thread.Sleep(100);
}
}