2009-12-29 81 views
6

我正在开发一个.NET项目,它需要与一些用户定义的类进行交互 - 被改为“作业”。所有工作类别必须实现特定的接口IJob,以便库消耗它们。有时候一个工作类可能拥有非托管资源,这需要明确处理。我应该如何确保处理可能的一次性物品?

我应该如何确保所有工作在使用后妥善处理,如果我事先不知道工作是否需要明确处置?我有几个想法我自己,而是想听听您的意见/建议:

  1. IJob : IDisposable,迫使所有的工作来实现Dispose()方法。这将允许我在using块中处理工作,但由于大多数工作是而不是预计需要明确处置,这可能会增加客户开发人员不必要的困惑。

  2. 是否涉及作业的所有工作try-finally块,并用finally,以确保如果作业实现IDisposableDispose()被调用。这使得客户更容易实施新的工作职位 - 不必实施空的方法 - 但它也隐藏了图书馆知道并关心一次性工作的事实。

写这篇后,我趋向于向解决方案#1瘦,但我仍然认为这将是很好看的替代解决方案,以及额外的优点/缺点两个我心中已经有了。

回答

8

同意有一个先例:数据流的基类是IDisposable的NAD因此所有流后裔。但是MemoryStream不需要Disposing。
但是,不要试图/最后,using() { }块是一个更方便的速记。

所以你的选择是:你想要所有的工作都是IDisposable或只是一些?

第一个选项会产生小的开销,第二个选项会让您更容易忘记在必要时处置(使用)。

+0

好点。但是,大部分流都需要处理,我希望只有少数工作需要处理。 – 2009-12-29 17:51:25

+0

在我看来'System.Web.IHttpModule'也需要它的实现者提供'Dispose()'方法,尽管只有少数模块(恕我直言)需要它。我想这为#1提供了额外的优先权。 – 2009-12-29 17:54:50

+1

+1,我认为,为Job提供一个标准化的方法来清理它使用的是合理的。通过使用'IDisposable',您可以从框架支持中受益,并且最终用户至少可以考虑在何处放置适当的清理代码。 – user7116 2009-12-29 18:00:14

2

我会去#2和文件,任何一次性物品将被丢弃。基本上,如果你拥有一个对象的所有权,你有义务处理实现IDisposable的对象。

如果你读过有效的C#/更有效的C#,比尔·瓦格纳给出相同的建议(我有明显;-)

+0

的OP已经在配置这两个选项所拥有的对象,所以我看不出这是一个选项#2的参数。 – 2009-12-30 13:10:45

3

我觉得这样。我宁愿开发人员实施一个空的Dispose方法,而忘记实施必要的方法Dispose

5

#2是如何构造foreach的作品。 Autofac的容器处理工作也是如此。

语义差别是你是否说工作本身一次性的,或实施是否可能一次性的。

从你的例子中可以清楚地看出,前者不是真实的,即工作本身不是一次性的。因此,我建议#2,但有一个扩展方法集中在try/finally

public static void Execute(this IJob job) 
{ 
    try 
    { 
     job.Run(); 
    } 
    finally 
    { 
     var disposableJob = job as IDisposable; 

     if(disposableJob != null) 
     { 
      disposableJob.Dispose(); 
     } 
    } 
} 
+0

+1,我喜欢你关于语义的观点,但是我想我会用第一种解决方案,因为其他答案中提到的原因和问题本身。 – 2009-12-29 20:24:45