代码之家  ›  专栏  ›  技术社区  ›  Jørn Schou-Rode dscher

我应该如何确保处理可能的一次性物品?

  •  6
  • Jørn Schou-Rode dscher  · 技术社区  · 15 年前

    我正在处理一个.NET项目,它需要与一些用户定义的类交互,这些类被称为“作业”。所有作业类都必须实现特定的接口 IJob 以便图书馆使用它们。有时,作业类可能包含需要显式释放的非托管资源。

    如果我事先不知道工作是否需要明确处理,我应该如何确保所有工作在使用后都得到正确处理?我自己也有一些想法,但想听听您的意见/建议:

    1. 制作 IJob : IDisposable ,强制所有作业实现 Dispose() 方法。这将允许我在 using 但正如大多数工作一样 预期需要显式处理,这可能会给客户端开发人员增加不必要的混乱。

    2. 做所有与工作有关的工作 try-finally 块和使用 finally 确保 释放() 如果作业实现,则调用 IDisposable . 这使得客户端更容易实现一个新的作业类-不必实现一个空的 处置() 方法——但它也隐藏了一个事实,即库知道并关心一次性工作。

    在写下这篇文章之后,我倾向于解决方案1,但我仍然认为看到其他的解决方案和我已经想到的另外两个优点/缺点是很好的。

    4 回复  |  直到 15 年前
        1
  •  8
  •   Henk Holterman    15 年前

    有一个先例:流基类是IDisposable NAD,因此所有流的后代都是。但MemoryStream不需要处理。
    但不要试图/最终 using() { } 布洛克是一种更方便的速记法。

    所以你的选择是:你想让所有的工作都是可分配的还是仅仅是一部分?

    第一个选项产生的开销很小,第二个选项使在必要时更容易忘记释放(使用)。

        2
  •  5
  •   Bryan Watts    15 年前

    #2是如何 foreach 施工工程。这也是Autopac处理集装箱的方式。

    语义上的区别在于你是否说工作本身 一次性的,或是否实现 可能是 可任意处理的。

    从你的例子中可以清楚地看到,前者不是真的,工作本身就不是一次性的。因此,我建议2,但使用扩展方法集中 try/finally :

    public static void Execute(this IJob job)
    {
        try
        {
            job.Run();
        }
        finally
        {
            var disposableJob = job as IDisposable;
    
            if(disposableJob != null)
            {
                disposableJob.Dispose();
            }
        }
    }
    
        3
  •  3
  •   Stan R.    15 年前

    我是这样想的。我希望开发人员实现一个空的 Dispose 方法而不是忘记实现必要的 处置 方法。

        4
  •  2
  •   James Keesey    15 年前

    我同意2并记录任何一次性物品将被处置。基本上,如果您拥有一个对象的所有权,那么您就有义务处置实现IDisposable的对象。

    如果你读到有效的C/更有效的C,比尔·瓦格纳给出同样的建议(我显然同意;-)