简体   繁体   English

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

[英]What is the proper way to dispose avalonia bitmap?

Iam using the Avalonia UI Framework to build a dotnet core MVVM app.我正在使用Avalonia UI 框架构建一个 dotnet 核心 MVVM 应用程序。
I want to display frames from a WebCam and created a simple WebCamViewModel:我想显示来自网络摄像头的帧并创建了一个简单的 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;
        }
    }

I tried the naiv approach and dispose the old bitmap like this:我尝试了 naiv 方法并像这样处理旧位图:

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

I get System.NullReferenceException: "Object reference not set to an instance of an object."我收到 System.NullReferenceException:“未将对象引用设置为对象的实例。” while resizing the application.在调整应用程序大小时。 StackTrace堆栈跟踪

  1. How can I properly dispose the old bitmap instances so that the GC doesn't have much to do?如何正确处理旧的位图实例,以便 GC 没有太多事情要做?

  2. Is there a better approach to display dynamic changing image content?有没有更好的方法来显示动态变化的图像内容?

There is a couple of question exist:有几个问题存在:

  1. OnFrame event should be unsubscribed, regardless if you use it per-application or per-something else. OnFrame 事件应该取消订阅,无论您是针对每个应用程序还是针对其他事物使用它。 This is just a good practise, like for example 'use using on disposable entities', if you by chance create multiple windows, or want to switch between multiple windows at zero cost or whatever happens.这只是一个很好的做法,例如“在一次性实体上使用”,如果您偶然创建了多个窗口,或者想以零成本在多个窗口之间切换或发生任何事情。 So this is a must:所以这是必须的:
public void Dispose()
{
     _service.OnFrame -= BitmapReceived;
}
  1. If bitmap is public accessable property - someone can reference it, be it DataBind or whatever AND unintentially using code MUST handle its lifetime - invoke Close/Dispose/Finish/or whatever.如果位图是公共可访问的属性——有人可以引用它,无论是数据绑定还是其他任何东西,并且无意中使用代码必须处理它的生命周期——调用关闭/处理/完成/或其他任何东西。 This invalid approach in UI will lead to problems where you should count references to this instance to manage it's death (And you will also encounter accidental NRE and other exception across app which you should just omit). UI 中的这种无效方法会导致问题,您应该计算对此实例的引用以管理它的死亡(并且您还会遇到意外的 NRE 和其他应忽略的应用程序异常)。 Instead, just create an event, in which disposing of this entity will be performed by user.相反,只需创建一个事件,其中该实体的处置将由用户执行。 This will render this property useless and you don't need any dispose:这将使此属性无用,您不需要任何处置:
public event EventHandler<Bitmap> OnFrame
{
    add
    {
        _service.OnFrame += value;
    }
    remove
    {
        _service.OnFrame -= value;
    }
}

This way you can perform required transformations on Bitmap before you feed it to View.通过这种方式,您可以在将 Bitmap 提供给 View 之前对其执行所需的转换。 This is why you choose MVVM in first place: view after transformation of model, transform before commiting to model.这就是您首先选择MVVM 的原因:模型转换后查看,提交模型之前转换。 It will probably be a good idea to switch to MVC for web cam experience instead.切换到MVC以获得网络摄像头体验可能是个好主意。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM