在图片框中设置图像时,“对象当前正在其他地方使用”异常

时间:2012-09-10 16:18:45

标签: c# wpf winforms

有了标题,有几个问题,但没有一个可以帮助我或指导我解决我的问题。

我正在使用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;
            }
      }

3 个答案:

答案 0 :(得分:5)

如果我正确理解了您的问题,您将从多个主题访问此图片框。 WinForms在引擎盖下使用GDI +,这不是线程安全的。 WinForms不会强制您仅从创建它们的线程访问UI对象。它让你做到了,但你最终会发现错误,正如你所发现的那样。

尝试从工作线程向您的GUI线程发布消息,以使GUI线程更新图片。这应该可以解决您所看到的错误。

如果转移到WPF,您将遇到类似的线程问题。 WPF严格强制只有创建UI对象的线程才能对其进行修改。在WPF中,您可以使用Invoke方法让正确的线程操作图片框。

否则如上所述,两者之间的性能差异不会很大。您应该考虑是否需要或更喜欢立即模式绘制到保留模式。表格是即时的,WPF保留。

答案 1 :(得分:1)

这两种技术都应该让你做你想做的事情。根据您以前的技能和经验以及项目的具体要求,哪个是更好的选择。

如果你问的是性能,如果你有一个相当简单的界面,没有太多元素,而且只是基本上显示一个大图像(然后你可以修改和更新),你将看不到winforms和wpf(没有3d,没有大的元素数)。

答案 2 :(得分:-2)

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

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