Link to home
Create AccountLog in
Avatar of Marc Davis
Marc DavisFlag for United States of America

asked on

System Service And File Delete

Hi All,

Maybe I'm missing something but I have a system service and I do a File.WriteAllBytes(bla, bla, ...)

Then I want to later, in the service execution, delete that file. The WriteAllBytes creates, opens and closes the file. So, the file should be closed.

Yet when, ater in the service execution, I l try to do a File.Delete(bla) of that temporary file I get an error that it cannot delete the file because it's in use by a process.

The file is a temp file and the only thing using it is the system service.

Am I missing something or is there no way of deleting that file unless the service is stopped and I use the OnStop to delete any and all temporary files?

Any information would be greatly appreciated.

Thanks
Avatar of Ioannis Paraskevopoulos
Ioannis Paraskevopoulos
Flag of Greece image

Hi,

Can you provide some code? In what other manner do you use this file? For a test you may try to delete it right after creating it. This will tell you if there is something wrong with the call or the service. I believe that it will be able to delete, so probably you try to access it or append something to it later in your code and not closing it correctly.

Giannis
Avatar of Marc Davis

ASKER

It's for an email. I create the file as a temporary file. I set some of the other email attributes like the To address, the From address, Subject and Message Body. I then take the file that was created and Attach it to the Attachments of an email.

Then I send the email with the System.Net.Mail. Upon successful continuation of that .send, I then want to delete that file that was in the attachment as it has been attached to the email.

But it's saying that it cannot delete it because there is another process that has it open. I have set waits with a thread.sleep for about 10 seconds and still nothing. The generated file is not all that large (22 KB) either.

If a system service should allow for the File.Delete of that, would/could it be the email? If so, that doesn't make a lot of sense because it's attached on the email and the email object was sent.

Any thoughs?
ASKER CERTIFIED SOLUTION
Avatar of Cong Minh Vo
Cong Minh Vo
Flag of Viet Nam image

Link to home
membership
Create an account to see this answer
Signing up is free. No credit card required.
Create Account
Hehe, we had exactly the same situation at work a while back. It seems that the attachment object was holding some references at the file even after sending the email.

Try to dispose the attachment object before deleting the file.

Giannis
Man.....I went to bed at night, woke up in the morning, checked email to see that i had a feedback 6 hours ago in a question i participated in, i sit down to answer as a normal geek would do first thing in the morning, just to see that after posting someone got first !!!!!
It seems like I am still encountering it even after the Dispose() of the attachment or the entire SMTPClient.

Do I need to do both or even if I just did the SMTPClient (which is the message including the attachment) would that not Displose of it all?
SOLUTION
Link to home
membership
Create an account to see this answer
Signing up is free. No credit card required.
Create Account
I tried and that did nothing still the same error.

In fact, my code is almost identical to the stack overflow link. However,  if you look at the details in that as well the person that did the OP never indicated the situation was resolved by the Dispose either. For all tense and purposes the Displose was not doing it then either.

Any ideas?

Thanks
Does anybody have any ideas? The code is doing the Dispose() and a GC.SuppressFinalize(this).

I was a little incorrect in how the code in the Stack Overflow was but the basic jhist is the same.

I call the Dispose of the MailMessage as well as the MailMessage.Attachments and it seems to call a constructor that populates the message again.

And in every case I look at the object to see if it's disposed and it says the disposed is a false.

If I'm calling the Dispose why would it not dispose?

Any thoughts/ideas?
Ok, not a constructor but it populates the message again.

But the question is still there on if I'm calling the Dispose() why would it not dispose? Or even flag is as disposed as a true rather than a false.

Again, any assistance is greatly appreciated.
Can you please provide actual code ?
But  why when a dispose is called on a object that uses IDisposable would it actually not Dispose or be flagged as disposed?
That might be a separate question so focusing back on the original.

In what way can I deleted an attached file from a send email from within a service?

I routinely encounter: "The process cannot access the file '{My Filename}' because it is being used by another process."

This happens when I try to Dispose of the Email object. I called the GC.SuppressFinalize as well which I see when I am running it through DEBUG but I still routinely encounter that message.

Anybody have any thoughts or ideas? The code itself it pretty extensive as it's comprised of an abstract class which does the "heavy lifting" and an interface for this portion.  But in nutshell it is sent with the following:

MailClient.Send(Test.MailMessage);

Then later after a successful send it will perform an:

Test.Dispose();

In there it will attempt to perform a File.Delete({My Filename}). That routinely encounters that error as well. I have tried to delete the file while on the service is running from a Windows Explorer and it says it's in use by the service name.

The above MailClient is defined with:

public SmtpClient MailClient
{
   ...etc
}


I am actually getting the email and everything so that it functioning but I am trying to cleanup by deleting the file I attached in the email. I do not need it anymore because it was temporary but it will NOT allow me to delete it because it says it's "in use".

Now, I do see the attachment in the Test.MailMailMessage and I always see the "Dispose" as "False".  The Test is the Interface:

public interface ITest : IDisposable
    {

        TestProperties Properties
        {
            get;
            set;
        }

        MailMessage MailMessage
        {
            get;
        }

    }

The abstract class contains the MailMessage for the "heaving lifting" portions.

The temporary file I'm attaching and trying to delete after a successful send of the email is created from within the abstract class added to the MailMessage.  

I routinely encounter that same error when attempting to delete the file with a File.Delete.

What is going on that it will not release the lock of that file? The Dispose should but obviously it is not.

Any thoughts or ideas on how that can be deleted would be greatly appreciated.

Thanks
Have you tried disposing the mailclient before the delete?
The MailClient which was from the SMTPClient:

public SmtpClient MailClient
{
   ...etc
}

It does not have a .Dispose() that I can call for it otherwise I would have tried that as well.

All, I see is:

Client Certificates
Credentials
Delivery Method
EnableSSL
Equals
GetHashCode
GetType
Host
PickupDeliveryLocation
Port
Send
SendAsync
SendAsyncCancel
SendCompleted
ServicePoint
TargetName
TimeOut
ToString
UseDefaultCredentials

Again, if I had it I would have tried that too.
Have you tried the using statement?

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

Declare your object in the parenthesis and move your code for emailing in the curly brackets. Then outside the curly brackets delete your file.
Actually, I tried the which :

((IDisposable)MailClient).Dispose();

as minhvc provided a link for his code project reference. That didn't work.

As per your link it states:

"The using statement ensures that Dispose is called even if an exception occurs while you are calling methods on the object. You can achieve the same result by putting the object inside a try block and then calling Dispose in a finally block; in fact, this is how the using statement is translated by the compiler."

SMTPClient in the .NET Framework 2.0, 3.0, 3.5 do not use IDisposable. In fact, the .NET 4.0 has that for the SMTPClient and you can call the .Dispose on that but I'm using .NET 3.5.
Anybody have any ideas/thoughts/suggestions?
Well, it turned out that nothing I did at any time would dispose that file so I could delete it. I was able to dispose at one other place and delete the file but when I did that I was unable to send the email.

The end result was that instead of creatiing a temporary file, I instead created a memorystream using a ToArray (converting it to bytes). An SMTP can send the Memeorystream so long at it's not closed. I displosed of it later and it allowed for that. I confirmed on a memory tool from Red Gate that it was actually not holding up in memory.

Although the file didn't get any traction and I suspect it's because of the service utilization but the same as what was mentioned on the Dispose held true on the memorystream.

Thank you both for the information. It was greatly appreciated.

Thanks