1

我和我的同事在 C# 的 Graphics 类中遇到了一个明显的错误。在我们的应用程序中,我们通过在其上绘制新事物来随着时间的推移更新位图。我们使用 Graphics.DrawImage(Image, Rectangle) 方法,有时调用永远不会返回,甚至会抛出异常。这是你们熟悉的问题吗?

这是我们的用例:

Bitmap whole = ...;

这在我们的问题出现之前就已经定义好了。正常的通话看起来像这样,“part”和“region”从网络进来:

Bitmap part = ...;
Rectangle region = ...;

using(var graphics = Graphics.FromImage(whole))
{
   using(part)
   {
      graphics.DrawImage(part, region); // Execution stops in here
   }
}

我们尝试对其设置超时:

...
      var someAttributes = ... part ...;

      var drawing = Task.Factory.StartNew(() => graphics.DrawImage(part, region));

      if (!drawing.Wait(5000))
      {
        // We put a breakpoint here
      }
...

我们尝试检查“部分”图像。通话前,看起来还可以;它没有被处置或任何东西,我们能够获得它的属性。但是在调用之后,它的所有成员都会抛出 InvalidOperationException。

如果我们让程序在此之后继续运行,下一次调用将每次都挂起。如果我们稍后暂停调试器,我们可以在线程视图中看到这些“绘图”任务仍在等待。

因此,如果您知道任何解决方法或防止这种行为的方法,我们将不胜感激您的帮助。

不久后编辑:

我们查看了图形对象,发现我们无法检查它,因为这个“对象当前正在其他地方使用”。我们认为这是对“整体”图像的唯一参考。我们甚至克隆了图像以将其显示在图片框中。我们阅读了 Clone 并发现,如果我们理解正确的话,它只做一个浅拷贝并且仍然与旧图像共享资源。

所以我们尝试替换

Rectangle subregion = ...;
Bitmap copy = whole.Clone(subregion);

Rectangle subregion = ...;
Bitmap copy = new Bitmap(whole.Clone(subregion));

它似乎解决了我们的问题。尽管在这种情况下 DrawImage 不会引发异常仍然是一个问题。

4

0 回答 0