使用前生成和处置?

Generate and Dispose before using?

今天我实习的导师说我应该使用

    HImage hi = null;

    HOperatorSet.GenEmptyObject(out hi);
    hi.Dispose();

    hi = f.GrabImageAsync(-1.0);

而不是

    HImage hi = null;

    hi = f.GrabImageAsync(-1.0);

使用的函数原型如下

    void HOperatorSet.GenEmptyObj(out HObject emptyObject);
    HImage HFramegrabber.GrabImageAsync(double maxDelay);

我尊重我的导师,但我没有看到在调用 hi = f.GrabImageAsync(-1.0); 之前创建和处置对象的任何有意义的解释,因为该函数 returns 是该对象的一个​​实例,因此不需要至少在我看来,首先生成和处理对象。

所以任何人都可以澄清是否真的需要它。提前谢谢你。

我同意你的看法。通常创建并立即处理变量是没有用的。

从代码中我们可以看出,HOperatorSet.GenEmptyObject 不与您的 f 变量交互,因此调用该方法没有任何意义。

此外,将 HImage hi 设置为 null 没有任何意义,因为这可能已经是默认设置,并且是使用 out 参数设置的。

所以我的赌注是:

HImage hi = f.GrabImageAsync(-1.0);

大多数时候调用Dispose()是为了释放所有不再需要的托管资源。因此,让我们假设 HOperatorSet.GenEmptyObject(out hi) 方法打开 FileStream 并保存对新 HImage 实例中某些字段的引用。稍后在代码中,您希望使用此 HImage 实例执行其他操作,而不再需要此 FileStream 或任何其他资源。现在是调用 hi.Dispose() 关闭它的好时机,然后再继续做任何其他事情。但在任何其他情况下,你的导师都会误导你。

WinForms 中有一些 类 具有多种用途,其中一些需要资源,而另一些则不需要。我最熟悉的是FontFont 实例封装了字体设置的组合以及 GDI 字体资源的 GDI 句柄。大多数 WinForms 控件的 Font 属性 setter 将导致控件从传入的字体对象复制设置并存储传入的 Font 引用的副本这样它可能会通过调用 属性 getter 返回,但不会导致控件实际使用传入的字体进行绘图。由于即使在释放后也可以从 Font 对象中读取设置,因此实际上可以在设置控件的 Font 属性时创建和释放 Font 对象;在某些情况下,它可以说是一种合理的最少邪恶的方法:

  1. 如果 Font 个对象被创建和丢弃而没有处理,通常不会导致太多的 GDI 资源消耗,但这种一厢情愿的想法并不代表好的设计。

  2. 在设置新值之前对控件的旧值 Font 调用 Dispose 的策略将要求每个控件拥有自己单独的 Font 对象,然后将封装控件永远不会使用的资源。一个优点是读取控件的 Font 属性 的代码将能够直接使用该 Font 对象进行绘制。

  3. 让控件保留对已释放字体对象的引用将使多个控件可以安全地共享同一个字体对象,并且比其他任何一种方法消耗更少的 GDI 资源。一个限制是任何读取控件的 Font 属性 并想要使用该字体绘制的代码都必须使用它来构造一个新的 Font 对象(并且可能处置使用后)。

恕我直言,在创建时立即处理 Font 对象是一种有用的模式这一事实表明,框架应该包含用于 描述 字体的单独类型(控件的 Font 属性 的目的)和封装 GDI 字体对象(Font 参数的目的到字符串绘制方法)。如果后一种类型包含 Dispose 而前一种类型不包含,那么就不会存在如何使用它们的问题。但是,由于存在 Font 类型以及将其用于那些不相交目的的代码,因此 eager-dispose 模式可能是一种合理的最少邪恶方法。

我不确定这种方法是否代表了您讲师示例中发生的事情,因为我不熟悉所涉及的类型。可能是 GenEmptyObject 返回的对象实际上没有分配任何资源,它的 Dispose 方法什么也不做(声明可以安全地放弃特定对象可能比调用 Dispose 过早地)但是如果对象获得了其预期用途不需要的资源,则早期处置可能是合适的if commented.