Читать книгу 📗 "Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю"
Обработка запроса на отмену
В текущий пример можно внести еще одно улучшение — предоставить пользователю способ для останова обработки данных изображений путем щелчка на второй кнопке Cancel (Отмена). К счастью, методы
Parallel.For()Parallel.ForEach()ParallelParallelOptionsCancellationTokenSourceПервым делом определите в производном от Window классе закрытую переменную-член
_cancelTokenCancellationTokenSourcepublic partial class MainWindow :Window{ // Новая переменная уровня Window. private CancellationTokenSource _cancelToken = new CancellationTokenSource(); ...}Обновите обработчик события
Clickprivate void cmdCancel_Click(object sender, EventArgs e){ // Используется для сообщения всем рабочим потокам о необходимости останова! _cancelToken.Cancel();}Теперь можно заняться необходимыми модификациями метода
ProcessFiles()private void ProcessFiles(){<b> // Использовать экземпляр ParallelOptions для хранения CancellationToken.</b> ParallelOptions parOpts = new ParallelOptions(); parOpts.CancellationToken = _cancelToken.Token; parOpts.MaxDegreeOfParallelism = System.Environment.ProcessorCount; // Загрузить все файлы *.jpg и создать новый каталог // для модифицированных данных. string[] files = Directory.GetFiles(@".TestPictures", "*.jpg", SearchOption.AllDirectories); string outputDirectory = @".ModifiedPictures"; Directory.CreateDirectory(outputDirectory); try { // Обработать данные изображения в параллельном режиме! Parallel.ForEach(files, parOpts, currentFile => { parOpts .CancellationToken.ThrowIfCancellationRequested(); string filename = Path.GetFileName(currentFile); Dispatcher?.Invoke(() => { this.Title = $"Processing {filename} on thread {Thread.CurrentThread.ManagedThreadId}"; }); using (Bitmap bitmap = new Bitmap(currentFile)) { bitmap.RotateFlip(RotateFlipType.Rotate180FlipNone); bitmap.Save(Path.Combine(outputDirectory, filename)); } }); Dispatcher?.Invoke(()=>this.Title = "Done!"); } catch (OperationCanceledException ex) { Dispatcher?.Invoke(()=>this.Title = ex.Message); }}Обратите внимание, что в начале метода конфигурируется объект
ParallelOptionsCancellationTokenCancellationTokenSourceParallelOptionsParallel.ForEach()Внутри логики цикла осуществляется вызов
ThrowIfCancellationRequested()OperationCanceledExceptionОбеспечение параллелизма задач с помощью класса Parallel
В дополнение к обеспечению параллелизма данных библиотека TPL также может использоваться для запуска любого количества асинхронных задач с помощью метода
Parallel.Invoke()System.ThreadingParallel.Invoke()TaskЧтобы взглянуть на параллелизм задач в действии, создайте новый проект консольного приложения по имени
MyEBookReaderProgram.csSystem.ThreadingSystem.TextSystem.Threading.TasksSystem.LinqSystem.Netwww.gutenberg.orgGetBook()