处理 avalonia 位图的正确方法是什么?

What is the proper way to dispose avalonia bitmap?

我正在使用 Avalonia UI 框架构建一个 dotnet 核心 MVVM 应用程序。
我想显示来自网络摄像头的帧并创建了一个简单的 WebCamViewModel:

    public class WebCamViewModel : ViewModelBase
    {
        private Bitmap webCamImage;

        public Bitmap WebCamImage
        {
            get { return webCamImage; }
            private set { this.RaiseAndSetIfChanged(ref webCamImage, value); }
        }

        public WebCamViewModel(WebCamImageService webcamImageService)
        {
            webcamImageService.OnFrame += BitmapReceived;            
        }

        public void BitmapReceived(Bitmap bitmap)
        {    
            WebCamImage = bitmap;
        }
    }

我尝试了 naiv 方法并像这样处理旧位图:

public void BitmapReceived(Bitmap bitmap)
        {    
            if (webCamImage != null) webCamImage.Dispose();
            WebCamImage = bitmap;
        }

我得到 System.NullReferenceException:“对象引用未设置到对象的实例。”在调整应用程序大小时。 StackTrace

  1. 如何正确处理旧位图实例,使 GC 无事可做?

  2. 是否有更好的方法来显示动态变化的图像内容?

存在几个问题:

  1. OnFrame 事件应该取消订阅,无论您是否使用它 per-application 或 per-something 其他。这只是一个很好的实践,例如 'use using on disposable entities',如果您偶然创建多个 windows,或者想以零成本或发生任何情况在多个 windows 之间切换。所以这是必须的:
public void Dispose()
{
     _service.OnFrame -= BitmapReceived;
}
  1. 如果位图 public 可访问 属性 - 有人可以引用它,无论是 DataBind 还是其他任何无意中使用的代码必须处理它的生命周期 - 调用Close/Dispose/Finish/or 随便吧。 UI 中的这种无效方法会导致问题,您应该计算对此实例的引用以管理它的死亡(并且您还会遇到意外的 NRE 和应用程序中的其他异常,您应该忽略这些异常)。相反,只需创建一个事件,在该事件中,该实体的处理将由用户执行。这将使这个 属性 无用,你不需要任何处置:
public event EventHandler<Bitmap> OnFrame
{
    add
    {
        _service.OnFrame += value;
    }
    remove
    {
        _service.OnFrame -= value;
    }
}

这样您就可以在将 Bitmap 提供给 View 之前对其执行所需的转换。这就是您首先选择 MVVM 的原因:模型转换后查看,提交模型前转换。切换到 MVC 来获得网络摄像头体验可能是个好主意。