1

我正在尝试从后台工作人员截取屏幕截图并显示在图片框中。

我的问题是我得到了这个例外:Exception has been thrown by the target of an invocation.

内部异常:Parameter is not valid.

有人可以解释为什么吗?

我正在使用这些using()块来防止内存泄漏。

public void DoStuff() {

    var bw = new BackgroundWorker();

    Bitmap b = null;

    bw.DoWork += delegate {

        Rectangle bounds = Screen.PrimaryScreen.Bounds;

        using(Bitmap bmp = new Bitmap(bounds.Width,
        bounds.Height,
        PixelFormat.Format32bppArgb)) {

            using(Graphics gfx = Graphics.FromImage(bmp)) {
                x.CopyFromScreen(bounds.X,
                bounds.Y,
                0,
                0,
                bounds.Size,
                CopyPixelOperation.SourceCopy);

                b = bmp;
            }
        }
    };

    bw.RunWorkerCompleted += delegate {
        pictureBox1.Image = b;
    };

    bw.RunWorkerAsync();
}
4

2 回答 2

2

如果要将位图分配给 PictureBox,则不应丢弃它。仅释放用于创建它的 Graphics 对象。当包含此 PictureBox 的 Form 被释放时,垃圾收集器将释放 Bitmap 实例。

另外,我建议您将图像作为参数传递给 RunWorkerCompleted,而不是在闭包中捕获它:

public void DoStuff()
{
    BackgroundWorker bw = new BackgroundWorker();

    bw.DoWork += (sender, args) =>
    {
        Rectangle bounds = Screen.PrimaryScreen.Bounds;
        Bitmap bmp = new Bitmap(bounds.Width, bounds.Height, PixelFormat.Format32bppArgb);
        using (Graphics gfx = Graphics.FromImage(bmp))
        {
            gfx.CopyFromScreen(
                bounds.X,
                bounds.Y,
                0,
                0,
                bounds.Size,
                CopyPixelOperation.SourceCopy
            );
        }
        args.Result = bmp;
    };

    bw.RunWorkerCompleted += (sender, e) =>
    {
        if (pictureBox1.Image != null)
        {
            pictureBox1.Image.Dispose();
        }
        pictureBox1.Image = (Bitmap)e.Result;
    };

    bw.RunWorkerAsync();
}
于 2012-12-13T11:57:26.297 回答
1

Darin 提供了非常好的分辨率。关于内存泛滥 - 您可以尝试调用 GC.Collect(); 处理图像后,尽管您可能会遇到性能问题。

于 2012-12-13T12:25:53.547 回答