C#使用多个线程完成单个任务

时间:2018-04-20 14:33:11

标签: c# multithreading

大家好日子。

我有一个旋转C#和线程的问题,我还是线程新手,我有一个基于线程的赋值。我的目标是让用户指定一定数量的线程,并根据这个数量,即应用程序需要使用多少线程来完成任务。

我的任务是使用中值3 x 3矩阵模糊图像。那部分我设法下降(可能不是最有效的代码)但现在我需要让可变数量的线程运行模糊方法,我完全迷失了它。

这是我的方法:

    public void Blur(Bitmap bmpInput)
    {

        Bitmap temp;
        float sumR, sumB, sumG;
        Color c;

        temp = bmpInput;

        for (int i = 0; i <= bmpInput.Width - 3; i++)
            for (int j = 0; j <= bmpInput.Height - 3; j++)
            {
                sumB = 0;
                sumG = 0;
                sumR = 0;
                for (int x = i; x <= i + 2; x++)
                    for (int y = j; y <= j + 2; y++) 
                    {
                        c = bmpInput.GetPixel(x, y);
                        sumR = sumR + c.R; 
                        sumG = sumG + c.G;
                        sumB = sumB + c.B;
                    }

                byte colorR = (byte)(sumR / 9);
                byte colorG = (byte)(sumG / 9);
                byte colorB = (byte)(sumB / 9);
                temp.SetPixel(i + 1, j + 1, Color.FromArgb(colorR, colorG, colorB));

            }
        temp.Save("C:\\Users\\Username\\Desktop\\whatever.jpg");

    }

这是另一种做同样事情的方法(虽然快一点)

    public static Bitmap MedianFiltering(Bitmap bm)
    {
        List<byte> termsList = new List<byte>();

        byte[,] image = new byte[bm.Width, bm.Height];



        //applying Median Filtering 
        for (int i = 0; i <= bm.Width - 3; i++)
            for (int j = 0; j <= bm.Height - 3; j++)
            {
                for (int x = i; x <= i + 2; x++)
                    for (int y = j; y <= j + 2; y++)
                    {
                        termsList.Add(image[x, y]);

                    }
                byte[] terms = termsList.ToArray();
                termsList.Clear();
                Array.Sort<byte>(terms);
                Array.Reverse(terms);
                byte color = terms[4];
                bm.SetPixel(i + 1, j + 1, Color.FromArgb(color, color, color));
            }
        return bm;

    }

此时我正在考虑“分割”图像并让每个线程将该方法应用于图像的一部分。

我的问题:如何在我的程序中实现线程。我之前从未使用过线程,大多数在线指南对我来说都像希腊语。

1 个答案:

答案 0 :(得分:1)

我们可以使用具有排队概念的任务库。由于任务库有效地使用核心。 让我们使用全局BlockingCollection来存储所有传入的Bitmap图像。

// BlockingCollection是threadSafe Collection

BlockingCollection<Bitmap> incomingBitmaps = new BlockingCollection<Bitmap>();

还有一个处理过的位图图像的全局BlockingCollection。

BlockingCollection<Bitmap> processedBitmaps = new BlockingCollection<Bitmap>();

让我们有三种方法负责  用于创建任务/线程
 读取传入的位图并存储到incomingBitmaps队列
 已处理的位图将被处理为processedBitmaps队列

   BlockingCollection<Bitmap> incomingBitmaps = new BlockingCollection<Bitmap>();
   BlockingCollection<Bitmap> processedBitmaps = new BlockingCollection<Bitmap>();
public static void  SpawnThreads()
 {
 List<Task> ReaderTasks = new List<Task>();
TaskFactory tfReader = new TaskFactory();

public List<Task> ProcessTasks = new List<Task>();
public TaskFactory tfProcess = new TaskFactory();

//you can create threads as many you want
 for (int i = 0; i <2; i++)
 {
ReaderTasks .Add(tfReader.StartNew(() => ReadBitmaps());
}
 for (int i = 0; i <5; i++)
 {
ProcessTasks.Add(tfProcess.StartNew(() => MedianFiltering());
}
}
public static void ReadBitmaps()
    {
//logic to get bitmap images
Bitmap bmp= GetBitmapImage();
incomingBitmaps.Add(bmp);
}

public static void MedianFiltering()
    {
 foreach (var bm in incomingBitmaps.GetConsumingEnumerable())
            {
        List<byte> termsList = new List<byte>();

        byte[,] image = new byte[bm.Width, bm.Height];

        //applying Median Filtering 
        for (int i = 0; i <= bm.Width - 3; i++)
            for (int j = 0; j <= bm.Height - 3; j++)
            {
                for (int x = i; x <= i + 2; x++)
                    for (int y = j; y <= j + 2; y++)
                    {
                        termsList.Add(image[x, y]);

                    }
                byte[] terms = termsList.ToArray();
                termsList.Clear();
                Array.Sort<byte>(terms);
                Array.Reverse(terms);
                byte color = terms[4];
                bm.SetPixel(i + 1, j + 1, Color.FromArgb(color, color, color));
            }
processedBitmaps.Add(bm);
}
  }

我们可以将processedBitmaps用于UI绑定。