Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю
Обработка запроса на отмену
В текущий пример можно внести еще одно улучшение — предоставить пользователю способ для останова обработки данных изображений путем щелчка на второй кнопке Cancel (Отмена). К счастью, методы
Parallel.For()
Parallel.ForEach()
Parallel
ParallelOptions
CancellationTokenSource
Первым делом определите в производном от Window классе закрытую переменную-член
_cancelToken
CancellationTokenSource
public partial class MainWindow :Window
{
// Новая переменная уровня Window.
private CancellationTokenSource _cancelToken =
new CancellationTokenSource();
...
}
Обновите обработчик события
Click
private 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);
}
}
Обратите внимание, что в начале метода конфигурируется объект
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
www.gutenberg.org
GetBook()