【问题标题】:C# Where to initialize IDisposable resource - within data class or data-object-list holders classC# 在哪里初始化 IDisposable 资源 - 在数据类或数据对象列表持有者类中
【发布时间】:2013-12-10 00:51:01
【问题描述】:

我需要从一个目录中提取许多视频文件并将它们拆分为音频和视频(通过 ffmpeg)并转换为 mxf 并通过第三方(开源)命令行工具进行加密。在加密时,该工具会生成密钥并将它们写入具有随机名称的文件中。所以我需要一个后台工作者(BGW)和一个文件观察者(FW)(他们都有一个 dispose 方法,所以我相信他们链接到非托管资源和应在使用后丢弃)。 我创建了一个类 - DrmConvertible (DC),它引用了原始视频路径,并且在函数调用中它完成了我需要的上述操作(模型)。还有另一个类从目录中读取所有文件并创建 DC 对象列表(如 viewModel 但不完全)。


我应该在哪里声明 FW 和 BGW ?

  1. 在 DC 类内部(保持封装,但每个对象都有一个实例 - 可能是 1000 秒)。
  2. 如果 point-01 那么它应该是全局的并在构造函数中初始化 - 它超出了类的范围(我不知道什么时候)。
  3. 如果 point-01 那么它是否应该在函数中是本地的,并且我在函数中显式初始化和处置它(我是否还注册和取消注册事件)。
  4. 在类(全局)和静态变量中,因此只维护一个实例,并且它超出了类的范围(我不知道什么时候)。这与在帮助类或服务中抽象它并初始化一次相同。
  5. 在外部类中(具有 DC 对象列表的视图模型 - 它破坏了封装但更容易 - 在当前上下文中)?

是否有针对这种情况的指导方针(数据持有者应该放什么,数据列表持有者应该放什么)?请不要让我看书代码完成[;)]

【问题讨论】:

  • @JensH:感谢您的全面回答。

标签: c# oop design-patterns idisposable


【解决方案1】:

我更喜欢在不再需要对象时立即处理它们。显然会占用资源,所以在我看来,最好的办法是初始化和处理它们尽可能靠近

所以我投票给你的第 3 项

由于您的对象实现了IDisposable 接口,您可以轻松地使用using 语句,它甚至会自动调用Dispose() 方法。没有比这更容易或更舒适的了。

是的,您将需要取消注册活动订阅!如果您不这样做,GarbageCollector 将使您的对象保持活动状态,即使它们可能已经超出范围。这将导致严重的内存泄漏,因为您无法处置超出范围的对象。

如果您不立即处置您的对象,有责任确保他们的资源稍后会被释放。这总是意味着更多的维护开销。所有引用非托管资源且在使用后未立即清理的对象都必须实现自己的Dispose() 方法。这可能会导致更长的处置层次结构。

因此,如果您像 第 1、2、4 和 5 项那样实现它,您仍然需要确保在 DC 上调用 Dispose() 的其他一些类。这可能会很困难,正如您自己说过的那样,您无法确定 DC 何时超出范围。 所以不要那样做!你在这里遇到麻烦了。

所以,我再次投票给第 3 项。此时您可以完全控制对象的生命周期以及何时不再需要它们。

【讨论】:

    【解决方案2】:

    在我看来,5 是你最好的选择。

    我希望有一个“组合根”,它可以创建一次 BGW 和 FW,然后将它们注入到任何需要它们的地方。完成所有操作后,“组合根”就可以释放了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-13
      • 2012-02-10
      • 1970-01-01
      • 2013-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-03
      相关资源
      最近更新 更多