How can I ensure the removal of possibly disposable items?

I am working on a .NET project that needs to interact with some user-defined classes, designated as "jobs." All job classes must implement a specific IJob interface so the library can consume them. Sometimes a job class may contain an unmanaged resource that must be explicitly deleted.

How should I guarantee that all tasks will be properly disposed of after use, if I do not know in advance if the work needs explicit disposal? I have some ideas, but I would like to hear your comments / suggestions:

  • Make IJob : IDisposable , forcing all jobs to implement the Dispose() method. This will allow me to work with jobs in using blocks, but since most jobs do not require explicit deletion, this can add unnecessary confusion for client developers.

  • Do all job work in the try-finally blocks and use finally to ensure that Dispose() is called if the job implements IDisposable . This makes it easier for customers to implement a new class of tasks - not having to implement an empty Dispose() method, but also hides the fact that the library knows and cares about one-time tasks.

After writing this, I am inclined toward solution No. 1, but I still think that it would be nice to see alternative solutions and additional pros and cons of the two, which I already have in mind.

+6
c # interface idisposable
source share
4 answers

There is a precedent: the Stream base class is IDisposable nad, so all descendant threads. But MemoryStream does not need to be disposed of.
But don't try / finally, using() { } block is a more convenient shorthand.

So, your choice: do you want all vacancies to be IDisposable or just some?

The first option takes a little overhead, the second makes it easy to forget Dispose (use) when necessary.

+8
source share

# 2 - how the foreach construct works. This is also how the Autofac container container works.

The semantic difference is whether you say that the work itself is one-time or implementation can be implemented.

It can be seen from your example that the first is not true, that jobs are not inherently disposable. Therefore, I recommend # 2, but using the extension method to centralize try/finally :

 public static void Execute(this IJob job) { try { job.Run(); } finally { var disposableJob = job as IDisposable; if(disposableJob != null) { disposableJob.Dispose(); } } } 
+5
source share

I think of it like that. I would rather have the developer implement the empty Dispose method than forget to implement the necessary Dispose method.

+3
source share

I would go with No. 2 and document that any disposable object will be deleted. In principle, if you take responsibility for an object, you must dispose of objects that implement IDisposable.

If you read "Effective C # / More Effective C #", Bill Wagner gives the same advice (with which I agree, obviously -)

+2
source share

All Articles