Теперь можно заняться необходимыми модификациями метода ProcessFiles()
private void ProcessFiles()
{
// Использовать экземпляр ParallelOptions для хранения CancellationToken.
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);
}
}
Обратите внимание, что в начале метода конфигурируется объект ParallelOptions
CancellationToken для применения маркера CancellationTokenSource. Кроме того, этот объект ParallelOptions передается во втором параметре методу Parallel.ForEach().Внутри логики цикла осуществляется вызов ThrowIfCancellationRequested()
OperationCanceledException, можно добавить в текст главного окна сообщение об ошибке.Обеспечение параллелизма задач с помощью класса Parallel
В дополнение к обеспечению параллелизма данных библиотека TPL также может использоваться для запуска любого количества асинхронных задач с помощью метода Parallel.Invoke()
System.Threading, но если нужна более высокая степень контроля над выполняемыми задачами, тогда следует отказаться от использования Parallel.Invoke() и напрямую работать с классом Task, как делалось в предыдущем примере.Чтобы взглянуть на параллелизм задач в действии, создайте новый проект консольного приложения по имени MyEBookReader
Program.cs пространства имен System.Threading, System.Text, System.Threading.Tasks, System.Linq и System.Net (пример является модификацией полезного примера из документации по .NET Core). Здесь мы будем извлекать публично доступную электронную книгу из сайта проекта Гутенберга (www.gutenberg.org) и затем параллельно выполнять набор длительных задач. Книга загружается в методе GetBook(), показанном ниже:using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Net;
using System.Text;
string _theEBook = "";
GetBook();
Console.WriteLine("Downloading book...");
Console.ReadLine();
void GetBook()
{
WebClient wc = new WebClient();