6

I've looked at a number of examples of how to use the AmazonS3Client and S3Response objects and never have I seen anyone bothering to dispose of them, which makes me wonder is there some implied knowledge that I am missing?

public class S3Response : IDisposable
{
    public void Dispose();
    ~S3Response();
}

public class AmazonS3Client : AmazonS3, IDisposable
{
    public void Dispose();
    ~AmazonS3Client();
}

They both clearly implement IDisposable (which is telling me I should be disposing them myself) but they also specify a destructor method, which (along with the aforementioned examples) is making me think have I missed something automagical?

Could it be that the destructor is calling Dispose behind the scenes? Surely it is bad form to perform this kind of magic behaviour.

Does anyone with more experience of the Amazon S3 service have any insight to offer?

gingerbreadboy
  • 7,386
  • 5
  • 36
  • 62

1 Answers1

3

First, Destructors are called automatically by the C# Garbage Collector when the object is marked as eligible for destruction, which then calls Finalize. Keep in mind, it could be a long time before the GC runs and decides to do this, and you don't have any real control over it besides manually calling the GC which is not recommended.

Most tutorials only show very basic usage of the libraries, you should definitely be disposing these objects yourself though. (or any object that implements IDisposable)

You of course could do it in a using statement

using(var client = new AmazonS3Client())
{
    // use the client here in the using scope
}
// the Dispose() is called after you leave scope of using statement

However, in general some objects are expensive to create (and destroy) and are more meant to be re-used for an extended period of time for several requests. In this case (and probably for the S3Client) you would keep and re-use the same reference to the S3Client for a longer duration then just one request. Keep in mind every time you instantiate the S3Client, it is probably authenticating with Amazon which is time-consuming and expensive.

Say you have a website using the S3Client. You probably want to re-use the same S3Client over the entirety of a web request, or even several web requests. You can achieve this by a Singleton pattern or even a dependency injector library like Unity which you can define an object Lifetime Manager which.

SlaterCodes
  • 1,139
  • 10
  • 21
  • 2
    Just a note: the client does not authenticate to Amazon when you create it - requests to the service are signed using the provided credentials when you actually call anything on the client. – wkl Jan 02 '14 at 22:20
  • @birryree ok thx makes sense. I was just trying to get the point across on why you may/may not want to dispose of objects after one use or re-use them. I re-use my Clients for the entirety of a web request. – SlaterCodes Jan 02 '14 at 22:24
  • These are all fine points which I have no argument with, however I am asking specificaly about `AmazonS3Client`s implementation rather than the generalities of `IDisposable`. – gingerbreadboy Jan 10 '14 at 10:23
  • @gingerbreadboy Specifically you asked if you are missing something about the deconstructor use. My answer is YES you need to dispose it manually and I recommend keeping an instance of the object alive and re-using it for several operations just remember to dispose it when you are eventually done. – SlaterCodes Jan 16 '14 at 00:21
  • @gingerbreadboy They are related, and it seems you don't understand the relation and how it effects your situation. If an object has a deconstructor, it is guaranteed to stay in the Generation 2 GC cycle. This means that you are waiting for a Gen2 GC before the GC calls the Finalizer on this object. This is very bad. You should read this post to understand why there is a Deconstructor, and why you should call Dispose even though it exists. http://stackoverflow.com/a/45087/602379 – SlaterCodes Feb 10 '14 at 21:42