0

我用 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. 

错误如下图所示:

图片

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

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

编辑:

在@Oscar 建议的更改后,我得到了这个错误

4

1 回答 1

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;
            }
        }   

}

随意移动锁,如有必要,可能会移动到您方法的最开始。

于 2013-06-17T14:06:58.973 回答