bitmap.Save(System.IO.Path.Combine(
outputDirectory, filename));
}
}
}
}
На заметку! В случае получения сообщения об ошибке, связанной с неоднозначностью имени Path между System.IO.Path и System.Windows.Shapes.Path, либо удалите оператор using для System.Windows.Shapes, либо добавьте System.IO к Path: System.IO.Path.Combine(...).
Обратите внимание, что метод ProcessFiles() выполнит поворот изображения в каждом файле *.jpg из указанного каталога. В настоящее время вся работа происходит в первичном потоке исполняемой программы. Следовательно, после щелчка на кнопке Click to Flip Your Images! (Щелкните для поворота ваших изображений) программа выглядит зависшей. Вдобавок заголовок окна также сообщит о том, что файл обрабатывается тем же самым первичным потоком, т.к. в наличии есть только один поток выполнения.
Чтобы обрабатывать файлы на как можно большем количестве процессоров, текущий цикл foreach можно заменить вызовом метода Parallel.ForEach(). Вспомните, что этот метод имеет множество перегруженных версий. Простейшая форма метода принимает совместимый с IEnumerable объект, который содержит элементы, подлежащие обработке (например, строковый массив files), и делегат Action, указывающий на метод, который будет выполнять необходимую работу.
Ниже приведен модифицированный код, где вместо литерального объекта делегата Action применяется лямбда-операция С#. Как видите, в коде
// Обработать данные изображений в параллельном режиме!
Parallel.ForEach(files, currentFile =>
{
string filename = Path.GetFileName(currentFile);
// Этот оператор теперь приводит к проблеме! См. следующий раздел.
// this.Title = $" Processing {filename} on thread
// {Thread.CurrentThread.ManagedThreadld}"
// Thread.CurrentThread.ManagedThreadld);
using (Bitmap bitmap = new Bitmap( currentFile))
using (Bitmap bitmap = new Bitmap(currentFile))
{
bitmap.RotateFlip(RotateFlipType.Rotate180FlipNone);
bitmap.Save(Path.Combine(outputDirectory, filename));
}
}
);
Доступ к элементам пользовательского интерфейса во вторичных потоках
Вы наверняка заметили, что в показанном выше коде закомментированы строки, которые обновляют заголовок главного окна значением идентификатора текущего выполняющегося потока. Как упоминалось ранее, элементы управления графического пользовательского интерфейса привязаны к потоку, где они были созданы. Если вторичные потоки пытаются получить доступ к элементу управления, который они напрямую не создавали, то при отладке программного обеспечения возникают ошибки времени выполнения. С другой стороны, если
На заметку! Не лишним будет повторить: при отладке многопоточного приложения вы иногда будете получать ошибки, когда вторичный поток обращается к элементу управления, созданному в первичном потоке. Однако часто после запуска приложение может выглядеть функционирующим корректно (или же довольно скоро может возникнуть ошибка). Если не предпринять меры предосторожности (описанные далее), то приложение в подобных обстоятельствах может потенциально сгенерировать ошибку во время выполнения.