在设置PictureBox中的图像时出现“对象正在其他地方使用”的异常。

4

对于这个标题,有几个问题,但都没有帮助我或指导我解决我的问题。

我正在使用C# winform构建一个实时或接近实时的图像应用程序。

但在winform中将图像分配给PictureBox

pictureBox.Image = image; 

该程序在5-20分钟内会随机抛出一个异常:Object is currently in use elsewhere.

我查阅了相关资料,但未找到解决方案。该错误是在程序从队列中简单地设置图像以显示时发生的,因此图像不可能在其他线程中被使用。

目前,我不确定WinForm是否是用于图像应用程序的正确平台。是否需要转移到另一个平台,如WPF?

我需要经验丰富的人士提供建议。

更新: 正如Nathanael指出的那样,我可以从多个线程访问picturebox,因此我假设多个线程可以访问picturebox的图像。因此,当我将上述行更改为以下内容时,就不再出现任何错误。

      private void SetImage(Bitmap image) 
      {
            if (this.pictureBox.InvokeRequired)
            {
                SetImageCallback callback = new SetImageCallback(SetImage);
                this.BeginInvoke(callback, new object[] { image });
            }
            else
            {
                pictureBox.Image = image;
            }
      }

我不确定转移到WPF会如何解决你的问题。 你没有注意到在WPF应用程序中出现了这个异常吗? - Vignesh.N
@VigneshNatraj 这就是为什么我要向有经验的人询问。您在WPF中是否也遇到了这个异常? - Tae-Sung Shin
我认为转移到WPF并不能解决异常问题,如果你的图像在程序中的其他地方被使用,你仍然会遇到这个异常。确保在与图像交互的类中正确实现IDisposable接口,并正确释放资源。 或者,您可以将图像转换为流,然后再从流中重建图像并显示在图片框中。 - Vignesh.N
嗯,我不确定你是否理解这个问题。我已经阅读了许多相关资料,但并没有好的解决方案。而且即使在单线程下使用帧率非常快的相机也会出现该错误。这促使我提出了这个问题。上述语句只是为了显示图像。如果不是另一种方式,为什么释放图像会解决这个问题呢? - Tae-Sung Shin
3个回答

5
如果我正确理解了您的问题,您从多个线程访问此图片框。WinForms在幕后使用GDI +,它不是线程安全的。WinForms不强制您仅从创建它们的线程访问UI对象。它允许您这样做,但最终会出现错误,正如您发现的那样。
尝试从工作线程向GUI线程发布消息,以便GUI线程更新图片。这应该解决您看到的错误。
如果您转移到WPF,则会遇到类似的线程问题。 WPF严格执行只有创建UI对象的线程才能对其进行修改。在WPF中,您可以使用Invoke方法使正确的线程操作您的图片框。
否则,两者之间的性能差异不会很大。您应该考虑是否需要或更喜欢立即模式绘图还是保留模式。Form是立即的,WPF是保留的。

1

这两种技术都应该能够让您很好地完成想做的事情。哪种选择更好取决于您以前的技能和经验以及项目的确切要求。

如果您关心性能,如果您有一个相当简单的界面,没有太多的元素,只是基本上显示一个大图像(然后修改和更新),则在winforms和wpf之间不会看到太大的性能差异(没有3D,没有大量的元素计数)。


没有一个Windows GUI API是线程安全的,因为它们都在单线程公寓(COM)模型中工作,并使用消息泵来排序消息。当他们说这个时,这意味着你必须在GUI线程上与GDI+组件进行交互。 - Slugart

-2
private void ThreadSafe(MethodInvoker method)
{
    try
    {
        if (InvokeRequired)
            Invoke(method);
        else
            method();
    }
    catch
    { }
}

///////////////////////
pictureBox1.Image = img;

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