0

我最近很快就了解到,在我的上下文中,所有的Cancellation标记都值得阻止任务被安排。我有很长时间的运行,我需要在等待中的任务中放弃单一方法的任务。我怎样才能做到这一点?我怎样才能放弃等待完成的任务?

我的第一个想法是让撕裂另一个线程的长时间运行的方法,但上面有一个循环,如果Cancellation.IsCancelled == true是不断检查,当它是true,我放弃托管长时间运行方法的线程。

这是不好的?有没有其他的方法?

顺便说一句,我长时间运行的任务是一个单一的方法,所以我可以检查取消令牌开始运行之前,或运行后,让我没有机会停止长时间运行的方法,例如,收集驱动器C上每个文件的所有FileInfo对象:!这是长时间运行的代码:

FileInfos = Mapper.Map<ObservableCollection<FileInfoViewModel>>(dirInfo.GetFiles($"*.{ext.TrimStart('.')}", SearchOption.AllDirectories)); 

我可以拆分成两个电话,并检查它们之间的令牌,但不会有太大的影响,我也可以重写CLR代码到我自己,和手动使用检查令牌的循环。这会起作用,但它闻起来非常糟糕。

+5

[是的,这很糟糕](http://stackoverflow.com/questions/1559255/whats-wrong-with-using-thread-abort)。调用'Thread.Abort()'应该被视为一个bug。你需要做合作取消 - 被取消的线程需要定期检查它是否被取消,并作出相应的反应。如果它不能这样做,那么放弃它可能更安全。 –

+3

你必须描述你的任务做什么以及为什么取消令牌不可用 –

+0

@SamiKuhmonen请参阅我的编辑。 – ProfK

回答

1

用于枚举文件系统实体的底层系统API已经支持取消 - 您只需确保使用正确的托管API。

DirectoryInfo.GetFiles将把枚举转换为一个数组 - 这意味着它只在所有数据被收集时才返回。另一方面,DirectoryInfo.EnumerateFiles将直接暴露枚举,并且您可以随时轻松停止评估。

仍然有一些不会被中断的位,但Thread.Abort无论如何不会对你有帮助 - Thread.Abort只会在托管代码中杀死线程,而实际需要时间的所有事情都是本机的,使用FindFirstFile/FindNextFile API。