Как я могу отменить ожидаемое задание?
Недавно я очень быстро узнал, что все Cancellation
Токен, в моем контексте, стоит предотвратить планирование задачи. У меня есть долго выполняющиеся задачи с одним методом, которые мне нужно прервать в ожидаемой задаче. Как мне этого добиться?
Моя первая идея состоит в том, чтобы позволить разорвать другой поток для метода длительного выполнения, но выше этого есть цикл, который продолжает проверять, Cancellation.IsCancelled == true
и когда это true
, Я прерываю поток, размещающий метод длительного запуска.
Это плохо? Есть ли другой способ?
Кстати, моя длительно выполняемая задача - это единственный метод, поэтому я могу либо проверить токен отмены до его запуска, либо после его запуска, и у меня нет возможности остановить метод длительного выполнения до его завершения, например, собрать все FileInfo
объекты для каждого файла на диске C:! Это долгосрочный код:
FileInfos = Mapper.Map<ObservableCollection<FileInfoViewModel>>(dirInfo.GetFiles($"*.{ext.TrimStart('.')}", SearchOption.AllDirectories));
Я мог бы разделить это на два вызова и проверить токен между ними, но это не будет иметь большого эффекта, или я могу переписать код CLR в свой собственный, и вручную использовать циклы, которые проверяют токен. Это будет работать, но пахнет очень плохо.
1 ответ
Базовый системный API, используемый для перечисления объектов файловой системы, уже поддерживает отмену - вам просто нужно убедиться, что вы используете правильный управляемый API.
DirectoryInfo.GetFiles
преобразует перечисляемый в массив - это означает, что он возвращает только тогда, когда все данные были собраны. С другой стороны, DirectoryInfo.EnumerateFiles
будет выставлять перечислимое напрямую, и вы можете легко остановить оценку в любой момент.
Есть еще несколько битов, которые не будут прерываться, но Thread.Abort
не помог бы тебе там в любом случае - Thread.Abort
убивает потоки только тогда, когда они находятся в управляемом коде, и все, что на самом деле требует времени, является нативным, используя FindFirstFile
/FindNextFile
API-интерфейсы.