使用以下代码,我们收到错误'目前正在其他地方使用对象'
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();
}
}
请提出建议。
答案 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方法。
因此,在尝试在线程中使用全局图像时要小心。大多数操作都不是线程安全的。