对象当前正在其他地方使用 - 当image.save时

4
使用以下代码时,我们遇到了“对象正在其他地方使用”的错误。
private void CaptureDone(System.Drawing.Bitmap e)
        {
            try
            {
                this.pictureBox.Image = e;
                 if (isSending)
                    ThreadPool.QueueUserWorkItem(new WaitCallback(SendVideoBuffer), pictureBox.Image);
            }
            catch (Exception) { }
        }

     void SendVideoBuffer(object bufferIn)
            {
    TcpClient tcp = new TcpClient(ConfigurationSettings.AppSettings[0].ToString(), 6000);
                           NetworkStream ns = tcp.GetStream();
                           if (ns != null)
                           {
                               System.Drawing.Image buffer = (System.Drawing.Image)bufferIn;
                               buffer.Save(ns, System.Drawing.Imaging.ImageFormat.Jpeg);// error comes here
                               ns.Close();
                               tcp.Close();
                            }
           }

请提供建议。


bufferIn 定义在哪里?处理 streams 时使用 using 块总是一个好主意。 - Mayank
@Mayank BufferIn 是一个对象。代码已更新,请检查。 - Anoop Mohan
@Mayank - 仍然出现相同的错误。 - Anoop Mohan
@Mayank - 请检查上传的图片。 - Anoop Mohan
让我们在聊天中继续这个讨论:http://chat.stackoverflow.com/rooms/13336/discussion-between-anoop-mohan-and-mayank - Anoop Mohan
显示剩余2条评论
2个回答

3

GDI+图像并不是线程安全的,您需要在对象上获取锁。

void SendVideoBuffer(object bufferIn) 
    { 

 var tcp = new TcpClient(ConfigurationSettings.AppSettings[0].ToString(), 6000); 
                   var ns = tcp.GetStream(); 
                   if (ns != null) 
                   { 
                       var buffer = (System.Drawing.Image)bufferIn;
                       lock(buffer) 
                            buffer.Save(ns, System.Drawing.Imaging.ImageFormat.Jpeg);
                       ns.Close(); 
                       tcp.Close(); 
        }
}

if(picturebox.InvokeRequired) { pictureBox.Invoke(new MethodInvoker( () => SendVideoBuffer(picturebox.Image))); } else SendVideoBuffer(picturebox.Image); - Mayank
这是问题的答案。 - Mayank

0

我之前遇到过这种异常,并对此有更多的发现。

这种异常大多数是由多线程引起的,我们试图操作同一个全局图像。

以下是一个很好的解释为什么会出现这个异常:“在WinForms中,这通常意味着存在递归的Graphics.GetHdc。GetHdc必须与ReleaseHdc匹配,然后才能进行任何其他GetHdc。递归意味着您有类似于GetHdc->GetHdc->ReleaseHdc->ReleaseHdc的东西,而不是GetHdc->ReleaseHdc->GetHdc->ReleaseHdc。另一种可能性是缺少对ReleaseHdc的调用(即GetHdc->GetHdc->ReleaseHdc)”。

深入了解image.Save方法,它将调用GetHdc->ReleaseHdc对方法。此外,我猜如果我们尝试获取image.width或image.Clone方法,它也会调用GetHdc方法。

因此,在尝试在线程中使用全局图像时要小心。大多数操作都不是线程安全的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接