• We've upgraded our forums. Please post any issues/requests in this thread.

StmpClient Problem in C#

Kreij

Senior Monkey Moderator
Staff member
Joined
Feb 6, 2007
Messages
13,817 (3.48/day)
Likes
5,524
Location
Cheeseland (Wisconsin, USA)
Processor Intel Core 2 Quad QX9650 Extreme @ 3.0 GHz
Motherboard Asus Rampage Formula
Cooling ZeroTherm Nirvana NV120 Premium
Memory 8GB (4 x 2GB) Corsair Dominator PC2-8500
Video Card(s) 2 x Sapphire Radeon HD6970
Storage 2 x Seagate Barracuda 320GB in RAID 0
Display(s) Dell 3007WFP 30" LCD (2560 x 1600)
Case Thermaltake Armor w/ 250mm Side Fan
Audio Device(s) SupremeFX 8ch Audio
Power Supply Thermaltake Toughpower 750W Modular
Software Win8 Pro x64 / Cat 12.10
#1
I create a file on disk from my app, and then I want to send the file via e-mail.
This works fine by creating an SmtpClient and using the Send() method.

When the send completed I want to delete the file as there is no reason to save it any longer.

Code:
.... Code for creating file
SmtpClient _Client = new SmtpClient();
.... code for client configuration

try
{
    _Client.Send(myFile);
}
catch()
{
     ... handle an exception
}

System.IO.File.Delete(myFile);
The Send() method is supposed to block until finished, but this throws a "File in use by another process" exception on the Delete method.

So I then tried running the whole thing in a BackgroundWorker and then doing the file delete in the RunWorkerCompleted event. This too throws the same error.

It's seems that SmtpClient process still has a handle attached to the thread, but I'm not sure why it is not letting it go when it's done with the send.

Any ideas?


Oops .. title was supposed to be SmtpClient not StmpClient.
 
Last edited:

FordGT90Concept

"I go fast!1!11!1!"
Joined
Oct 13, 2008
Messages
20,921 (6.24/day)
Likes
10,022
Location
IA, USA
System Name BY-2015
Processor Intel Core i7-6700K (4 x 4.00 GHz) w/ HT and Turbo on
Motherboard MSI Z170A GAMING M7
Cooling Scythe Kotetsu
Memory 2 x Kingston HyperX DDR4-2133 8 GiB
Video Card(s) PowerColor PCS+ 390 8 GiB DVI + HDMI
Storage Crucial MX300 275 GB, Seagate 6 TB 7200 RPM
Display(s) Samsung SyncMaster T240 24" LCD (1920x1200 HDMI) + Samsung SyncMaster 906BW 19" LCD (1440x900 DVI)
Case Coolermaster HAF 932 w/ USB 3.0 5.25" bay
Audio Device(s) Realtek Onboard, Micca OriGen+
Power Supply Enermax Platimax 850w
Mouse SteelSeries Sensei RAW
Keyboard Tesoro Excalibur
Software Windows 10 Pro 64-bit
Benchmark Scores Faster than the tortoise; slower than the hare.
#2
I would make a second thread and public List<string>. The second worker thread just loops every five seconds or so and attempts to delete the files in the List<string> collection. If it succeeds, remove it from the list, if it fails, keep it in the list until next time.

I would only use this approach if the file is in a temp dir where it is a copy and won't be missed.


If that doesn't work either, instead of deleting using File.Delete, launch cmd.exe with the del [path] command. That worked in situations where File.Delete wouldn't.
 

FordGT90Concept

"I go fast!1!11!1!"
Joined
Oct 13, 2008
Messages
20,921 (6.24/day)
Likes
10,022
Location
IA, USA
System Name BY-2015
Processor Intel Core i7-6700K (4 x 4.00 GHz) w/ HT and Turbo on
Motherboard MSI Z170A GAMING M7
Cooling Scythe Kotetsu
Memory 2 x Kingston HyperX DDR4-2133 8 GiB
Video Card(s) PowerColor PCS+ 390 8 GiB DVI + HDMI
Storage Crucial MX300 275 GB, Seagate 6 TB 7200 RPM
Display(s) Samsung SyncMaster T240 24" LCD (1920x1200 HDMI) + Samsung SyncMaster 906BW 19" LCD (1440x900 DVI)
Case Coolermaster HAF 932 w/ USB 3.0 5.25" bay
Audio Device(s) Realtek Onboard, Micca OriGen+
Power Supply Enermax Platimax 850w
Mouse SteelSeries Sensei RAW
Keyboard Tesoro Excalibur
Software Windows 10 Pro 64-bit
Benchmark Scores Faster than the tortoise; slower than the hare.
#3
Oh, if Send causes the thread to pause until complete, you shouldn't need the second thread. You might just need to have the shell delete the file instead of your app.

I know I used cmd to copy a file that another application had a write stream open on. .NET would refuse to touch it but cmd didn't complain. It copied the file and then I could open a read stream on the copy and delete the copy once I was done.


I guess the question is: does the SMTP Client ever release the file (at least within reason)?
 
Joined
Feb 1, 2010
Messages
178 (0.06/day)
Likes
46
Location
~/
System Name Slackware Linux
Processor yes
Motherboard yes
Cooling currently convection, but considering mineral oil
Memory sometimes fails due to too much beer
Video Card(s) ATI Radeon HD5570 series
Storage IDE
Display(s) 32" LCD TV
Case sometimes
Audio Device(s) huh? what? speak up, I can't hear you
Power Supply yes
Software Slackware running Open-Source software (it doesn't get any better)
#4

FordGT90Concept

"I go fast!1!11!1!"
Joined
Oct 13, 2008
Messages
20,921 (6.24/day)
Likes
10,022
Location
IA, USA
System Name BY-2015
Processor Intel Core i7-6700K (4 x 4.00 GHz) w/ HT and Turbo on
Motherboard MSI Z170A GAMING M7
Cooling Scythe Kotetsu
Memory 2 x Kingston HyperX DDR4-2133 8 GiB
Video Card(s) PowerColor PCS+ 390 8 GiB DVI + HDMI
Storage Crucial MX300 275 GB, Seagate 6 TB 7200 RPM
Display(s) Samsung SyncMaster T240 24" LCD (1920x1200 HDMI) + Samsung SyncMaster 906BW 19" LCD (1440x900 DVI)
Case Coolermaster HAF 932 w/ USB 3.0 5.25" bay
Audio Device(s) Realtek Onboard, Micca OriGen+
Power Supply Enermax Platimax 850w
Mouse SteelSeries Sensei RAW
Keyboard Tesoro Excalibur
Software Windows 10 Pro 64-bit
Benchmark Scores Faster than the tortoise; slower than the hare.
#5
According to that, it won't be fixed until .NET 4.0 (Visual Studio 2010) which isn't officially out yet.
 

Kreij

Senior Monkey Moderator
Staff member
Joined
Feb 6, 2007
Messages
13,817 (3.48/day)
Likes
5,524
Location
Cheeseland (Wisconsin, USA)
Processor Intel Core 2 Quad QX9650 Extreme @ 3.0 GHz
Motherboard Asus Rampage Formula
Cooling ZeroTherm Nirvana NV120 Premium
Memory 8GB (4 x 2GB) Corsair Dominator PC2-8500
Video Card(s) 2 x Sapphire Radeon HD6970
Storage 2 x Seagate Barracuda 320GB in RAID 0
Display(s) Dell 3007WFP 30" LCD (2560 x 1600)
Case Thermaltake Armor w/ 250mm Side Fan
Audio Device(s) SupremeFX 8ch Audio
Power Supply Thermaltake Toughpower 750W Modular
Software Win8 Pro x64 / Cat 12.10
#6
That seems to be a different issue (not gracefully releasing the connection using QUIT).
I don't know how long SmtpClient keeps a handle on the file, and the rather frustrating part is that there is no good way in .Net to check for "file in use."

It seems that many people simply try to open a stream to the file and if it throws an exception because it is in use, retry until it succeeds, and then do whatever they want to do with the file.

This is a rather "expensive" way of checking to see if a file is in use.
You can also get a list of process handles, but you have to leave the realm of managed code to do it and this too seems like overkill. It's kind of like stopping at every house in the neighborhood to see if your friend lives there when you have his address in your pocket.

I can code around this by deleting the files at a different point in time, like looking for leftover files from a previous module run when the module starts, but that just doesn''t sit too well with my "clean up when your done" programming mentality. :D

Maybe I will just launch a GC thread at application start that periodically (once every 5 minutes or so) checks for the temporary files and deletes them if it can. (shrug)

@Ford : You're getting dangerously close to 5k posts. :toast: Do you have a custom title picked out yet?
 
Last edited:

FordGT90Concept

"I go fast!1!11!1!"
Joined
Oct 13, 2008
Messages
20,921 (6.24/day)
Likes
10,022
Location
IA, USA
System Name BY-2015
Processor Intel Core i7-6700K (4 x 4.00 GHz) w/ HT and Turbo on
Motherboard MSI Z170A GAMING M7
Cooling Scythe Kotetsu
Memory 2 x Kingston HyperX DDR4-2133 8 GiB
Video Card(s) PowerColor PCS+ 390 8 GiB DVI + HDMI
Storage Crucial MX300 275 GB, Seagate 6 TB 7200 RPM
Display(s) Samsung SyncMaster T240 24" LCD (1920x1200 HDMI) + Samsung SyncMaster 906BW 19" LCD (1440x900 DVI)
Case Coolermaster HAF 932 w/ USB 3.0 5.25" bay
Audio Device(s) Realtek Onboard, Micca OriGen+
Power Supply Enermax Platimax 850w
Mouse SteelSeries Sensei RAW
Keyboard Tesoro Excalibur
Software Windows 10 Pro 64-bit
Benchmark Scores Faster than the tortoise; slower than the hare.
#7
Opening a file stream isn't expensive. I'm pretty sure it comes straight from the NTFS table and it doesn't seek the hard drive unless you start reading or writing.

This is what I'd do (pseudocode):

Code:
internal volitile List<string> _DeleteFiles = new internal List<string>();
private Thread _Thread = null;
public void Start()
{
  _Thread = new Thread(Worker);
  _Thread.Start();
}
public void Stop()
{
  if (_Thread != null)
    _Thread.Abort();
}

public void Worker()
{
  while (true)
  {
    for (int i = _DeleteFiles.Count - 1; i >= 0; i--)
    {
      try
      {
        File.Delete(_DeleteFiles[i]);
        _DeleteFiles.RemoveAt(i);
      }
      catch  { }
    }
    Thread.Sleep(5000);
  }
}
If you got a file you want to delete, add it to the _DeleteFiles collection.
 
Joined
Dec 13, 2007
Messages
2,758 (0.75/day)
Likes
465
#8
This might be too simple... but have you tried closing myfile?

Code:
.... Code for creating file
SmtpClient _Client = new SmtpClient();
.... code for client configuration

try
{
    _Client.Send(myFile);
}
catch()
{
     ... handle an exception
}
System.IO.File.Close(myfile);
{
System.IO.File.Delete(myFile);
 

FordGT90Concept

"I go fast!1!11!1!"
Joined
Oct 13, 2008
Messages
20,921 (6.24/day)
Likes
10,022
Location
IA, USA
System Name BY-2015
Processor Intel Core i7-6700K (4 x 4.00 GHz) w/ HT and Turbo on
Motherboard MSI Z170A GAMING M7
Cooling Scythe Kotetsu
Memory 2 x Kingston HyperX DDR4-2133 8 GiB
Video Card(s) PowerColor PCS+ 390 8 GiB DVI + HDMI
Storage Crucial MX300 275 GB, Seagate 6 TB 7200 RPM
Display(s) Samsung SyncMaster T240 24" LCD (1920x1200 HDMI) + Samsung SyncMaster 906BW 19" LCD (1440x900 DVI)
Case Coolermaster HAF 932 w/ USB 3.0 5.25" bay
Audio Device(s) Realtek Onboard, Micca OriGen+
Power Supply Enermax Platimax 850w
Mouse SteelSeries Sensei RAW
Keyboard Tesoro Excalibur
Software Windows 10 Pro 64-bit
Benchmark Scores Faster than the tortoise; slower than the hare.
#9
myFile is of type MailMessage (so File.Delete(myFile) will always error--can't delete MailMessage). So the files he would need to delete are probably under myFile.Attachments (an AttachmentCollection), no?

This has an example:
http://msdn.microsoft.com/en-us/library/system.net.mail.mailmessage.attachments.aspx

Code:
            MailMessage message = new MailMessage(
               "jane@contoso.com",
               "ben@contoso.com",
               "Quarterly data report.",
               "See the attached spreadsheet.");

            // Create  the file attachment for this e-mail message.
            Attachment data = new Attachment(file, MediaTypeNames.Application.Octet);
            // Add time stamp information for the file.
            ContentDisposition disposition = data.ContentDisposition;
            disposition.CreationDate = System.IO.File.GetCreationTime(file);
            disposition.ModificationDate = System.IO.File.GetLastWriteTime(file);
            disposition.ReadDate = System.IO.File.GetLastAccessTime(file);
            // Add the file attachment to this e-mail message.
            message.Attachments.Add(data);
What exactly are you trying to delete? If there isn't attachments, myFile = null would suffice.
 
Last edited:

Kreij

Senior Monkey Moderator
Staff member
Joined
Feb 6, 2007
Messages
13,817 (3.48/day)
Likes
5,524
Location
Cheeseland (Wisconsin, USA)
Processor Intel Core 2 Quad QX9650 Extreme @ 3.0 GHz
Motherboard Asus Rampage Formula
Cooling ZeroTherm Nirvana NV120 Premium
Memory 8GB (4 x 2GB) Corsair Dominator PC2-8500
Video Card(s) 2 x Sapphire Radeon HD6970
Storage 2 x Seagate Barracuda 320GB in RAID 0
Display(s) Dell 3007WFP 30" LCD (2560 x 1600)
Case Thermaltake Armor w/ 250mm Side Fan
Audio Device(s) SupremeFX 8ch Audio
Power Supply Thermaltake Toughpower 750W Modular
Software Win8 Pro x64 / Cat 12.10
#10
Ford is correct. It's a PDF file that is created using the ReportDocument.ExportToDisk() method and then added as an attachment to the MailMessage.

@Cracker ... There is no System.IO.File.Close() method.
 
Joined
Dec 13, 2007
Messages
2,758 (0.75/day)
Likes
465
#11
Ford is correct. It's a PDF file that is created using the ReportDocument.ExportToDisk() method and then added as an attachment to the MailMessage.

@Cracker ... There is no System.IO.File.Close() method.
o ok so it's physical never on the HD then? hince can't do the file.close method? never work with reportdocument or mailmessage yet.
 

FordGT90Concept

"I go fast!1!11!1!"
Joined
Oct 13, 2008
Messages
20,921 (6.24/day)
Likes
10,022
Location
IA, USA
System Name BY-2015
Processor Intel Core i7-6700K (4 x 4.00 GHz) w/ HT and Turbo on
Motherboard MSI Z170A GAMING M7
Cooling Scythe Kotetsu
Memory 2 x Kingston HyperX DDR4-2133 8 GiB
Video Card(s) PowerColor PCS+ 390 8 GiB DVI + HDMI
Storage Crucial MX300 275 GB, Seagate 6 TB 7200 RPM
Display(s) Samsung SyncMaster T240 24" LCD (1920x1200 HDMI) + Samsung SyncMaster 906BW 19" LCD (1440x900 DVI)
Case Coolermaster HAF 932 w/ USB 3.0 5.25" bay
Audio Device(s) Realtek Onboard, Micca OriGen+
Power Supply Enermax Platimax 850w
Mouse SteelSeries Sensei RAW
Keyboard Tesoro Excalibur
Software Windows 10 Pro 64-bit
Benchmark Scores Faster than the tortoise; slower than the hare.
#12
Ford is correct. It's a PDF file that is created using the ReportDocument.ExportToDisk() method and then added as an attachment to the MailMessage.
So is ExportToDisk or the Attachment not releasing the file? Can you try deleting the file after performing ExportToDisk to rule that out?
 
Last edited:

Kreij

Senior Monkey Moderator
Staff member
Joined
Feb 6, 2007
Messages
13,817 (3.48/day)
Likes
5,524
Location
Cheeseland (Wisconsin, USA)
Processor Intel Core 2 Quad QX9650 Extreme @ 3.0 GHz
Motherboard Asus Rampage Formula
Cooling ZeroTherm Nirvana NV120 Premium
Memory 8GB (4 x 2GB) Corsair Dominator PC2-8500
Video Card(s) 2 x Sapphire Radeon HD6970
Storage 2 x Seagate Barracuda 320GB in RAID 0
Display(s) Dell 3007WFP 30" LCD (2560 x 1600)
Case Thermaltake Armor w/ 250mm Side Fan
Audio Device(s) SupremeFX 8ch Audio
Power Supply Thermaltake Toughpower 750W Modular
Software Win8 Pro x64 / Cat 12.10
#13
I haven't had time to work on this problem, but thanks for the input guys.

I am assuming (I know, that's bad) that ExportToDisk() is releasing the file otherwise SmtpClient would have problems opening it to send it as an attachment.

Of course, with some if the internals of .Net it's anyone's guess. :D
 

FordGT90Concept

"I go fast!1!11!1!"
Joined
Oct 13, 2008
Messages
20,921 (6.24/day)
Likes
10,022
Location
IA, USA
System Name BY-2015
Processor Intel Core i7-6700K (4 x 4.00 GHz) w/ HT and Turbo on
Motherboard MSI Z170A GAMING M7
Cooling Scythe Kotetsu
Memory 2 x Kingston HyperX DDR4-2133 8 GiB
Video Card(s) PowerColor PCS+ 390 8 GiB DVI + HDMI
Storage Crucial MX300 275 GB, Seagate 6 TB 7200 RPM
Display(s) Samsung SyncMaster T240 24" LCD (1920x1200 HDMI) + Samsung SyncMaster 906BW 19" LCD (1440x900 DVI)
Case Coolermaster HAF 932 w/ USB 3.0 5.25" bay
Audio Device(s) Realtek Onboard, Micca OriGen+
Power Supply Enermax Platimax 850w
Mouse SteelSeries Sensei RAW
Keyboard Tesoro Excalibur
Software Windows 10 Pro 64-bit
Benchmark Scores Faster than the tortoise; slower than the hare.
#14
It depends on how Attachments work. If it is just copying a link and not the bytes, ExportToDisk() might be the culprit.