处理 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
如何正确处理旧位图实例,使 GC 无事可做?
是否有更好的方法来显示动态变化的图像内容?
存在几个问题:
- OnFrame 事件应该取消订阅,无论您是否使用它 per-application 或 per-something 其他。这只是一个很好的实践,例如 'use using on disposable entities',如果您偶然创建多个 windows,或者想以零成本或发生任何情况在多个 windows 之间切换。所以这是必须的:
public void Dispose()
{
_service.OnFrame -= BitmapReceived;
}
- 如果位图 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 来获得网络摄像头体验可能是个好主意。
我正在使用 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
如何正确处理旧位图实例,使 GC 无事可做?
是否有更好的方法来显示动态变化的图像内容?
存在几个问题:
- OnFrame 事件应该取消订阅,无论您是否使用它 per-application 或 per-something 其他。这只是一个很好的实践,例如 'use using on disposable entities',如果您偶然创建多个 windows,或者想以零成本或发生任何情况在多个 windows 之间切换。所以这是必须的:
public void Dispose()
{
_service.OnFrame -= BitmapReceived;
}
- 如果位图 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 来获得网络摄像头体验可能是个好主意。