Цель:
Я делаю простое приложение для обработки изображений, которое использует задачи для многопоточности. Пользователь выбирает изображение из папки, и оно отображается в PicBox. Когда он вводит количество потоков, тип цвета для изменения и значение (0-255) этого типа цвета (R, G, B) и нажимает кнопку редактирования, изображение выглядит следующим образом:
Процедура
- Преобразуется в байтовый массив
- Возвращается массив байтов, и точка поворота вычисляется в соответствии с номером потока.
- Создается список задач, и каждой задаче назначается начальный и конечный индекс большего массива байтов.
- В методе небольшая часть большего байта (от начала до конца индекса) сохраняется в меньший массив байтов.
- Затем метод преобразует небольшой массив байтов в изображение и возвращает изображение.
Проблема:
Все идет нормально, пока на 5-м шаге я не пытаюсь преобразовать массив байтов в изображение. В частности, это происходит, когда начальный индекс больше 0, что происходит во время выполнения 2-й задачи. Он работает ine для 1-й задачи. Может быть, он не может принять начальный индекс> 0?
Пожалуйста, изучите следующий код:
Код
List<Task<Image>> processImgTask = new List<Task<Image>>(threadCount);
threadCount = Convert.ToInt32(threadCombox.SelectedItem);
interval = imgArray.Length / threadCount;
for (int i = 0; i < threadCount; i++)
{
Start = End;
End += interval;
if (i == threadCount - 1)
{
End = imgArray.Length;
}
object data = new object[3] { Start, End, imgArray };
processImgTask.Add(new Task<Image>(ImgProcess, data));
}
//Task.WaitAll(processImgTask);
//EDIT followed by comments and answer
Parallel.ForEach(processImgTask, task =>
{
task.Start();
taskPicbox.Image = task.Result;
});
private Image ImgProcess(object data)
{
object[] indexes = (object[])data;
int Start=(int)indexes[0];
int End = (int)indexes[1];
byte[] img = (byte[])indexes[2];
List<byte> splitArray = new List<byte>();
for (int i =Start;i<End;i++)
{
splitArray.Add(img[i]);
}
byte[] b = splitArray.ToArray();
//Error occurs here when task 2 (thread 2) is being executed->
Image x = (Bitmap)((new ImageConverter()).ConvertFrom(b));
//System.ArgumentException: 'Parameter is not valid.'
return x;
}
foreach (Task<Image> task in processImgTask) { task.Start(); taskPicbox.Image = task.Result; // <----- blocking }
? - person Jeroen van Langen   schedule 14.04.2020Parallel.Foreach()
для этого. Это связано с процессором. - person Jeroen van Langen   schedule 15.04.2020Image x = (Bitmap)((new ImageConverter()).ConvertFrom(b));
откуда взялась переменнаяdata
? Я думаю, что шаг 5 неясен. Затем метод преобразует небольшой массив байтов в изображение и возвращает изображение. Если вы хотите создать изображения меньшего размера, вы должны передать задаче небольшое изображение. - person Jeroen van Langen   schedule 15.04.2020object data = new object[3] { Start, End, imgArray };
здесь imgArray — это большой массив исходного изображения, преобразованный в массив byte[]. В методе ImgProcess большой массив проходится от начального до конечного индекса, чтобы создать меньший byte[]. затем этот массив преобразуется в изображение и возвращается. - person Zextro   schedule 15.04.2020