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

私は以前にそのような例外に遭遇し、それについてさらに多くの根拠があります。

この例外のほとんどの理由は、同じ1つのグローバルイメージを操作しようとするマルチスレッドが原因です。

この例外が発生する理由は次のとおりです。「WinFormsでは、通常、再帰的なGraphics.GetHdcが発生します。GetHdcは他のGetHdcよりも前にReleaseHdcと一致する必要があります。再帰的とは、GetHdc->GetHdc->ReleaseHdc-のようなものがあることを意味します。 > GetHdc-> ReleaseHdc-> GetHdc-> ReleaseHdcの代わりにReleaseHdc。別の可能性として、ReleaseHdcへの呼び出しが欠落している可能性があります(つまり、GetHdc-> GetHdc-> ReleaseHdc)」。

image.Saveメソッドをさらに深く掘り下げると、GetHdc->ReleaseHdcペアメソッドが呼び出されます。また、image.widthまたはimage.Cloneメソッドを取得しようとすると、GetHdcメソッドも呼び出されると思います。

したがって、スレッドでグローバルイメージを使用する場合は注意が必要です。ほとんどの操作はスレッドセーフではありません。

于 2015-12-03T02:21:06.773 に答える