我想绘制mandelbrot集,用两个线程。分别绘制奇数列,偶数列。
但setpixel时候对bitmap的访问总是无法 互斥。 用 lock  monitor  mutex 都不行。private static Bitmap t = new Bitmap(640, 480);        private Thread draw1 = null;
        private Thread draw2 = null;
        private static Mutex mutex = new Mutex();        private void Draw()
        {
            draw1 = new Thread(new ThreadStart(DrawMandelbrot_Odd));
            draw2 = new Thread(new ThreadStart(DrawMandelbrot_Even));
            draw1.Start();
            draw2.Start();
            pictureBox1.Image = t;
        }        private void DrawMandelbrot_Odd() 
        {
            for (int i = 0; i < pictureBox1.Width; i += 2)
            {
             for (int j = 0; j < pictureBox1.Height; j++)
                {  
                    int k;
                    for (k = 0; k < m_Times; k++)
                    {
                      
                    }
                    Color c = ;
                    lock (this)
                    {
                        mutex.WaitOne();
                        t.SetPixel(i, j, c);
                        mutex.ReleaseMutex();
                    }
                 }
            }
        }
        private void DrawMandelbrot_Even()
        {
            for (int i = 1; i < pictureBox1.Width; i += 2)
            {
                for (int j = 0; j < pictureBox1.Height; j++)
                {
                    x0 = 0;
                    y0 = 0;
                    double p = (double)pmin + dp * i;
                    double q = (double)qmin + dq * j;
                    int k;
                    for (k = 0; k < m_Times; k++)
                    {
                        getNextIter(iterTimes, x0, y0, p, q, out x, out y);
                        r = x * x + y * y;
                        x0 = x;
                        y0 = y;
                        if (r > m_Deep)
                            break;                    }
                    red = ;
                    green = ;
                    blue = ;
                    Color c = Color.FromArgb(red, green, blue);
                    lock (this)
                    {
                        mutex.WaitOne();
                        t.SetPixel(i, j, c);
                        mutex.ReleaseMutex();
                    }
                }
            }
        }
总是在 t.SetPixel(i, j, c);处 出错, 说对象正在被使用。我少打了好多代码,

解决方案 »

  1.   

    你是想弄出来动画效果么?这样是弄不出来的Bitmap这个对象不能被两个线程同时持有,线程互斥不是这么用的。你可以在两个线程中分别绘制图形(都持有自己的bitmap对象),然后再两个线程都完成之后通知UI线程再合并两个图片
      

  2.   


    用 64*48 这类小尺度画布, 偶尔可以绘制成功,大部分时候都绘制到一半,调试出错。
    UI合并可以吗? 合并之后存在哪个变量里?  picturebox.image里面行吗? 或者某bitmap也行。求指教
      

  3.   

    楼主可以试试以下代码,不保证成功: 
    private static Bitmap t = new Bitmap(640, 480);        private Thread draw1 = null;
            private Thread draw2 = null;
            private static object _writeLock=new object();
    private autoEvents = new AutoResetEvent[]
            {
                new AutoResetEvent(false),
                new AutoResetEvent(false)
            };
            private void Draw()
            {
                draw1 = new Thread(new ThreadStart(DrawMandelbrot_Odd));
                draw2 = new Thread(new ThreadStart(DrawMandelbrot_Even));
                draw1.Start();
                draw2.Start();
    WaitHandle.WaitAll(autoEvents);
                pictureBox1.Image = t;
            }        private void DrawMandelbrot_Odd()
            {
                for (int i = 0; i < pictureBox1.Width; i += 2)
                {
    for (int j = 0; j < pictureBox1.Height; j++)
                    { 
                        int k;
                        for (k = 0; k < m_Times; k++)
                        {
                          
                        }
                        Color c = ;
                        SetPixel(i, j, c);
                    }
                }
    autoEvents[0].Set();
            }
            private void DrawMandelbrot_Even()
            {
                for (int i = 1; i < pictureBox1.Width; i += 2)
                {
                    for (int j = 0; j < pictureBox1.Height; j++)
                    {
                        x0 = 0;
                        y0 = 0;
                        double p = (double)pmin + dp * i;
                        double q = (double)qmin + dq * j;
                        int k;
                        for (k = 0; k < m_Times; k++)
                        {
                            getNextIter(iterTimes, x0, y0, p, q, out x, out y);
                            r = x * x + y * y;
                            x0 = x;
                            y0 = y;
                            if (r > m_Deep)
                                break;                    }
                        red = ;
                        green = ;
                        blue = ;
                        Color c = Color.FromArgb(red, green, blue);
                        SetPixel(i, j, c);
                    }
                }
    autoEvents[1].Set();
            } private void SetPixel(int i,int j,Color c)
    {
    lock(_writeLock)
    {
    try
    {
     t.SetPixel(i, j, c);
    }
    catch ()
    {
    }
    }
    }