c#中的线程冲突

时间:2013-06-17 14:00:51

标签: c# .net multithreading thread-safety threadpool

我在C#中编写了以下代码:

private void myEnqThread()
        {
            Bitmap temp = null;
            temp = getScreen();
            if(temp!=null)
                queueScreen.Enqueue(temp);
        }

        private Bitmap getScreen(){
            System.Drawing.Bitmap bitmapDesktop;
            System.Drawing.Graphics graphics;
            System.IntPtr hWndForeground;// = System.IntPtr.Zero;

            RECT rect = new RECT();
            bitmapDesktop = null;
            graphics = null;
            hWndForeground = System.IntPtr.Zero;

            bitmapDesktop = new Bitmap
            (
                System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width,
                System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height,
                System.Drawing.Imaging.PixelFormat.Format24bppRgb
            );

            graphics = System.Drawing.Graphics.FromImage(bitmapDesktop);
            graphics.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size);
            hWndForeground = GetForegroundWindow();
            GetWindowRect(hWndForeground, out rect);
            graphics.DrawRectangle(Pens.Red, rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top);
            return bitmapDesktop;
        }

可以存在多个执行方法myEnqThread()的线程 例如:

Thread oThreadEnqueue = new Thread(new ThreadStart(myEnqThread));
oThreadEnqueue.Start();
Thread oThreadEnqueue2 = new Thread(new ThreadStart(myEnqThread));
oThreadEnqueue2.Start();

我收到了错误:

ArgumentException not managed. 

错误如下图所示:

image

我认为只有当多个线程尝试访问该操作时才会发生这种情况,因为当我只使用一个线程尝试相同的代码时,没有问题。

我可以做些什么来解决这个问题?我可以锁定资源吗?

修改

@Oscar建议更改后,我收到this错误

1 个答案:

答案 0 :(得分:0)

在调用

之前,您似乎需要创建一个锁
graphics.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size);

我建议在finally块中的代码中对所有IDisposbale实例(如Graphics和Bitmap)调用Dispose()。

编辑:刚刚修改了你的代码。它没有经过测试,所以要小心。

public class MyClass{

private static readonly Object objLock = new Object();
private void myEnqThread()
        {
            Bitmap temp = null;
            temp = getScreen();
            if(temp!=null)
                queueScreen.Enqueue(temp);
        }

        private Bitmap getScreen(){
            System.Drawing.Bitmap bitmapDesktop;
            System.Drawing.Graphics graphics;
            System.IntPtr hWndForeground;// = System.IntPtr.Zero;

            RECT rect = new RECT();
            bitmapDesktop = null;
            graphics = null;
            hWndForeground = System.IntPtr.Zero;
            lock(objLock){
                bitmapDesktop = new Bitmap
                (
                        System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width,
                    System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height,
                    System.Drawing.Imaging.PixelFormat.Format24bppRgb
                );

                graphics = System.Drawing.Graphics.FromImage(bitmapDesktop);
                hWndForeground = GetForegroundWindow();
                GetWindowRect(hWndForeground, out rect);
                graphics.DrawRectangle(Pens.Red, rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top);
                return bitmapDesktop;
            }
        }   

}

如果需要,请随意移动锁定,或者在方法的最开始。