4

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

我正在使用 C# winform 构建实时或近实时成像应用程序。

但是在winform中将图像分配给PictureBox

pictureBox.Image = image; 

Object is currently in use elsewhere.基本上在 5-20 分钟内给出一个随机异常。

我搜索了有关此问题的材料,但找不到正确的解决方案。当程序只是将图像设置为从队列中显示时发生错误。因此,图像无法在其他线程中使用。

在这一点上,我不确定 winform 是否适合成像应用程序。我是否必须转移到另一个平台,例如 WPF?

我需要有经验的建议。

更新:正如 Nathanael 指出的,我可以从多线程访问图片框,所以我假设多线程可以访问图片框的图像。因此,当我将上面的行更改为以下行时,我不再收到任何错误。

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

3 回答 3

5

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

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

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

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

于 2012-09-10T17:39:20.220 回答
1

这两种技术都应该允许你做你想做的事。取决于您以前的技能和经验以及项目的确切要求,哪个是您更好的选择。

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

于 2012-09-10T17:21:24.893 回答
-2
private void ThreadSafe(MethodInvoker method)
{
    try
    {
        if (InvokeRequired)
            Invoke(method);
        else
            method();
    }
    catch
    { }
}

///////////////////////
pictureBox1.Image = img;
于 2016-02-10T12:53:43.157 回答