Question

I recently came across a situation where the Dispose method had to be hard-coded in a C# program. Otherwise the file used in an email will be "forever" locked and not even Process Manager was able to tell me who/what locked it. I had to use Unlocker Assistant to force delete the file, but I fear now I've left some allocated memory blocks on the server.

The code I am referring to is this:

MailMessage mail = new MailMessage();
mail.From = new MailAddress("reception@domain.com", "###");
mail.Subject = "Workplace Feedback Form";
Attachment file = new Attachment(uniqueFileName);
mail.Attachments.Add(file);
mail.IsBodyHtml = true;
mail.CC.Add("somebody@domain.com");
mail.Body = "Please open the attached Workplace Feedback form....";

//send it
SendMail(mail, fldEmail.ToString());

The above code left the file from uniqueFileName locked by the Attachment handle and I was not able to delete it and because this code ran from a client machine (not from the server itself), the handle to the file was impossible to find.

After I had forced a deletion the files, I found from another forum that I should have Disposed of the Attachment object.

So I added these lines of code after the email was sent ...

//dispose of the attachment handle to the file for emailing, 
//otherwise it won't allow the next line to work.
file.Dispose(); 

mail.Dispose(); //dispose of the email object itself, but not necessary really
File.Delete(uniqueFileName);  //delete the file 

Should I have wrapped this in a using statement instead?

And that's the crux of my question. When should we use Using and when should we use Dispose? I hope there is a clear distinction between the two which says if you do "X" then use this, else use that.

This When to Dispose? and this C# Dispose : when dispose and who dispose it do answer my question somewhat, but I am still confused about the "conditions" on when to use either.

Was it helpful?

Solution 2

Should I have wrapped this in a using statement instead?

Either that or put the main code in a try block and the Dispose in a finally block.

using just implements the Dispose pattern safely with less code. using will put Dispose in a finally block so that the object is disposed even if an exception is thrown. The way you have it now, if an exception is thrown, the objects will not be disposed and will instead be cleaned up when garbage collected.

I have never run across a case where I can't use using and must manually use a try/finally with Dispose().

So the choice is yours - you could just use Dispose in a finally block and it would likely be the same as if you used using.

OTHER TIPS

using in C#:

using(MyDisposableType obj = new MyDisposableType())
{
  ...
}

is "syntactic sugar" (or short-hand notation) that is equivalent to

MyDisposableType obj = new MyDisposableType();
try {
  ...
} finally {
  obj.Dispose();
}

as described in http://msdn.microsoft.com/en-us//library/yh598w02.aspx

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top