0

最近我在访问位图方面遇到了很多烦人的 问题,我开始认为我需要重新评估我的应用程序的设计。

目前,我有一个对象可以创建另外两个对象。其中一个提供一系列位图(例如来自网络摄像头),另一个提供一系列坐标对(例如来自鼠标或触摸板)。父对象具有子对象生成的事件的侦听器。这些事件具有自定义参数,它们将新信息(位图或坐标)作为有效负载携带。例如:

public class NewImageEventArgs : EventArgs
{
    public NewImageEventArgs(Bitmap image)
    {
        Image = image;
    }
    public Bitmap Image { get; private set; }
}

父对象中的侦听器方法将有效负载复制到对象级表示。当任一侦听器(位图或坐标)被触发时,它们随后会调用一个共享方法,该方法同时使用位图和坐标进行一些计算。

private void PointerModule_NewPosition(object sender, NewPositionEventArgs e)
{
    this.p = e.Position;
    this.Invalidated();
}

在我看来,OutOfMemory 和 InvalidOperation(“对象当前在别处使用”)异常中反复出现的问题源于每个新事件可能位于不同线程上的事实。在一个线程上使用位图时,当另一个线程尝试同时访问它时会引发异常。

我需要从根本上改变程序的形状吗?我可以采取任何预防措施来消除此类问题吗?

4

1 回答 1

0

编辑:我重读了您的问题,我可能回答的问题与您提出的问题略有不同。然而,我用“对象在其他地方使用”例外解决了同样的问题,我学到的教训总结在底部的链接中。bitmap.Clone() 和 new Bitmap(source) 都不会创建深层图像副本。这导致了异常。

在我的应用程序中,我使用模式:

public class ImageProvider()
{
public event EventHandler LiveImageUpdated;
private object _currentImageLock = new object();

private Bitmap _currentImage;
public Bitmap CurrentImage
{ 
    get    
      {
       lock (_currentImageLock)
         {
            return DeepImageCopy(_currentImage)
         }
       }
     private set
     {
       lock(_currentImageLock)
       {
            _currentImage = value
       }
        if (LiveImageUpdated != null)
        {
          foreach (Delegate del in LiveImageUpdated.GetInvocationList())
          {
              EventHandler handler = (EventHandler)del;
              handler.BeginInvoke(this, EventArgs.Empty, null, null);
           }
        }
     }
}

}

我问了这个问题: How to create a Bitmap deep copy

应用程序没有问题。所以基本上我跳过了将新图像作为参数推送的部分,听众要求图像的深层副本,他们没有共享图像。在性能方面,它可以毫无问题地工作。

于 2012-10-04T11:44:36.577 回答