【发布时间】:2020-04-14 20:51:57
【问题描述】:
目标:
我正在制作一个简单的图像处理应用程序,它使用 Tasks 进行多线程处理。用户从文件夹中选择图像并将其显示在 PicBox 中。当他输入线程数、要改变的colorType和该colorType(R,G,B)的Value(0-255),然后点击编辑按钮,图像为:
程序
- 转换为字节数组
- 返回字节数组,并根据线程号计算主元。
- 创建任务列表,并为每个任务分配一个较大字节数组的开始和结束索引
- 在该方法中,将较大字节的小部分(从开始到结束索引)保存到较小的字节数组中
- 该方法然后将小字节数组转换为Image并返回图像
问题:
一切都很好,直到第五步我尝试将字节数组转换为图像。它特别发生在开始索引大于 0 时,即在第二个任务执行期间。它适用于第一个任务。难道是它不能接受开始索引> 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 }? -
我会为此使用
Parallel.Foreach()。它受 CPU 限制。 -
所以你正在将较小的字节数组转换成多个图像?
Image x = (Bitmap)((new ImageConverter()).ConvertFrom(b));data变量从何而来?我认为第 5 步不清楚 “该方法然后将小字节数组转换为 Image 并返回图像” 如果要创建较小的图像,则应为任务提供小图像。 -
object data = new object[3] { Start, End, imgArray };这里的 imgArray 是原始图像转换为 byte[] 数组的大数组。在 ImgProcess 方法中,从开始到结束索引遍历大数组以创建较小的 byte[]。然后将此数组转换为图像并重新生成。
标签: c# multithreading image-processing task