合并图像时出现C#Threading Lock错误

Bog*_*dan 4 c# multithreading locking

我正在尝试创建一个多线程程序,从一个图片框中获取某个位图,每个线程分析并更改其中的一部分,然后将其保存回图片框.我已经使用了一个lock()来处理共享位图对象和图片框的指令,但由于某种原因,我仍然每6-10次运行得到"对象目前在其他地方使用"错误.

     private Object locker = new Object();

     void doThread(Bitmap bmp2) //simplified - other references not important
     {
        //some code here
        //....  
        lock (locker)
        {
            Graphics gr = Graphics.FromImage(bmp2); //this is where i get the errors, they're related to bmp2
            gr.DrawImage(bmp, new Rectangle(0, 0, 800, 600));
            gr.Dispose();

            pictureBox1.Image = bmp2;
        }
     }

     void runThreads()
     {
        Bitmap bmp2 = new Bitmap(pictureBox1.Image);

        Thread thread1 = new Thread(delegate() { doThread(bmp2); }); 
        Thread thread2 = new Thread(delegate() { doThread(bmp2); });
        Thread thread3 = new Thread(delegate() { doThread(bmp2); });
        Thread thread4 = new Thread(delegate() { doThread(bmp2); });

        thread1.Start();
        thread2.Start();
        thread3.Start();
        thread4.Start();
    }
Run Code Online (Sandbox Code Playgroud)

我试着尽可能多地读取lock()方法,但它仍然有点不清楚所以我可能会误用它.所以我的问题是,为什么锁不阻止线程执行指令?我误用了吗?或者我有可以使用的解决方法吗?

非常感谢任何帮助.

Jar*_*Par 5

原因是变量pictureBox1与GUI线程具有亲缘关系.您无法访问它并从单独的后台线程更改它的值.要更改值,必须从与变量关联的线程中执行此操作.这通常通过.Invoke完成

试试这个

pictureBox1.Invoke((MethodInvoker)(() => pictureBox1.Image = bmp2));
Run Code Online (Sandbox Code Playgroud)

即便如此,我认为你仍然有问题,因为值bmp2是从多个线程使用的.pictureBox1当后台线程在其上创建图形对象时,该变量将尝试在GUI线程上呈现此值.