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

请提出建议。

4

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(); 
        }
}
于 2012-07-03T05:46:55.893 回答
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 方法。

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

于 2015-12-03T02:21:06.773 回答