c#multithreading - 共享位图,锁和信号量

时间:2016-04-05 18:34:59

标签: c# multithreading bitmap locking

目前我有一个带有pictureBox的表格。表格绘制围绕光标的圆圈中的3个轨道。每个'轨道'根据轨道的特定参数,它是一个单独的对象,它每1度旋转一次自己的线程更新位置。在主程序中,我为每个轨道调用绘图功能,具体取决于最快的轨道,所以它不会断断续续。

现在,一切都很好,但我不能一次只能通过一个线程访问Bitmap。添加信号量/锁定,延迟目前在其他地方使用的""错误,但没有阻止它。锁(/信号量)被传递给构造函数中的每个Orbital。

这里是更新代码,在线程中调用刷新显示:

private void UpdateDisplay()
    {
        // get fresh display
        Lock.AcquireWriterLock(-1);
            Display = (Bitmap)(Background.Clone());
        Lock.ReleaseWriterLock();
        // draw all orbitals
        foreach (Orbital item in Orbitals)
        {
            item.Draw(Display);
        }
        // update the display
        Lock.AcquireWriterLock(-1);
            pictureBox1.Image = Display;
        Lock.ReleaseWriterLock();
    }

这是对象轨道的Draw方法:

    public void Draw(Bitmap bitmap)
    {
        // draw a square 
        int maxX = OrbitalX + OrbitalSizeRadius;
        int maxY = OrbitalY + OrbitalSizeRadius;
        for (int i = OrbitalX - OrbitalSizeRadius; i < maxX; i++)
        {
            for (int j = OrbitalY - OrbitalSizeRadius; j < maxY; j++)
            {
                Lock.AcquireWriterLock(-1);
                    // check for eventual offscreen pixels
                    if (BoundaryControl.Check(i, j, bitmap.Width, bitmap.Height))
                    {
                        bitmap.SetPixel(i, j, OrbitalColor);
                    }
                Lock.ReleaseWriterLock();
            }
        }
    }

我认为锁定/等待是伪原子的,但从它的外观来看,它不是,除非我理解这些错误的方式。

编辑:

有关错误的更多细节。始终在随机时间跳到pictureBox1.Image = Display;行:经过一半旋转到几次完全旋转。

An unhandled exception of type 'System.InvalidOperationException' occurred in System.Drawing.dll

Additional information: Object is currently in use elsewhere.

关于在轨道内处理锁的代码:

// declaration
private ReaderWriterLock Lock;

// constructor
public Orbital(int radius, double speed, int sizeRadius, Color color, int startingRotation, bool counterClockwise, ReaderWriterLock thelock)
    {
        /*
         * bunch of assigns
         */
        Lock = thelock;
    }

在Form类中:

// declaration
private ReaderWriterLock Lock;

// initialization
Lock = new ReaderWriterLock();

// passing to Orbital as an argument
// Orbitals is an ArrayList
Orbitals.Add(new Orbital(100, 10, 5, Color.IndianRed, 0, false, Lock));

1 个答案:

答案 0 :(得分:0)

神秘解决,锁定完美无缺。分享显示确实是一个问题,但解决它显示&#39;另一个引发完全相同错误的隐藏问题。