对象目前在别处使用 - 当image.save时

时间:2012-07-03 05:38:31

标签: c# wpf

enter image description here使用以下代码,我们收到错误'目前正在其他地方使用对象'

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

请提出建议。

2 个答案:

答案 0 :(得分: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(); 
        }
}

答案 1 :(得分:0)

之前我遇到过这样的例外,并且有更多的基础。

此异常的大部分原因是由多线程引起的,我们尝试操作同一个全局图像。

这里有一个很好的解释为什么会发生这种异常:"使用WinForms,这通常意味着会出现递归的Graphics.GetHdc。 GetHdc必须在任何其他GetHdc之前匹配ReleaseHdc。递归意味着你有像GetHdc-> GetHdc-> ReleaseHdc-> ReleaseHdc,而不是GetHdc-> ReleaseHdc-> GetHdc-> ReleaseHdc。另一种可能性是缺少对ReleaseHdc的调用。 (即GetHdc-> GetHdc-> ReleaseHdc)"。

深入到image.Save方法更多,它将调用GetHdc-> ReleaseHdc对方法。另外,我想如果我们尝试获取image.width或image.Clone方法,它也会调用GetHdc方法。

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