473,385 Members | 1,780 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

the process cannot access the file '' because it is being used by another process...

HaLo2FrEeEk
404 256MB
I've got a program that downloads a set of thumbnail images specified in a remote XML file. There can be up to 30 thumbnails downloaded. I'm using a foreach loop iterating through an XmlNodeList of all the <item> tags in the XML file and inside that foreach loop I start a new Thraed that runs the downloadThumb method. Here is my downloadThumb method:

Expand|Select|Wrap|Line Numbers
  1. public void downloadThumb(object Url)
  2.         {
  3.             string url = Url.ToString();
  4.             Uri parts = new Uri(url);
  5.             string query = parts.Query;
  6.             string filename = query.Replace("?ssid=", "");
  7.             if(!File.Exists("./thumbs/" + filename + "-Thumbnail.jpg"))
  8.             {
  9.                 HttpWebRequest thumbreq = (HttpWebRequest)WebRequest.Create(url);
  10.                 HttpWebResponse thumbres = (HttpWebResponse)thumbreq.GetResponse();
  11.                 BinaryReader thumb = new BinaryReader(thumbres.GetResponseStream());
  12.                 FileStream fstream = new FileStream("./thumbs/" + filename + "-Thumbnail.jpg", FileMode.Create, FileAccess.Write);
  13.                 BinaryWriter file = new BinaryWriter(fstream);
  14.                 byte[] thumbnail = thumb.ReadBytes((int)thumbres.ContentLength);
  15.                 file.Write(thumbnail);
  16.                 file.Close();
  17.                 thumb.Close();
  18.                 fstream.Close();
  19.                 thumbres.Close();
  20.             }
  21.         }
Probably not the prettiest way, but it's the only way I could get it to write the thumbnail images properly to disk.

Anyway, I want the ./thumbs/ folder (with all the images inside) to be deleted when I close the program. I set up this in my .designer.cs file:

this.Closing += new System.ComponentModel.CancelEventHandler(this.Form _Closing);

And my Form_Closing method:

Expand|Select|Wrap|Line Numbers
  1. public void Form_Closing(object sender, CancelEventArgs cArgs)
  2.         {
  3.             dataGridView1.Dispose();
  4.             if (Directory.Exists("./thumbs"))
  5.             {
  6.                 Directory.Delete("./thumbs", true);
  7.             }
  8.         }
dataGridView1 being the datagridview that I'm posting the information I'm parsing out of the XML file to. I figured that because I'm displaying the thumbnail I'm downloading inside a dataGridViewImageCell that disposing the dataGridView would sever the association with the files...that's not the case. I need to know how I can disassociate the process with those files so I can delete them automatically. Can I get some help?
Nov 24 '09 #1
27 10157
Plater
7,872 Expert 4TB
If you open an Image or Bitmap object from a file, it counts as the file being in use
Nov 24 '09 #2
tlhintoq
3,525 Expert 2GB
Can we see the code that you use to open the thumbnails from the local harddrive?

I'm going to guess that you are using a loop that loads the thumbs into a list or array.

Expand|Select|Wrap|Line Numbers
  1. for (int Index =0; Index<30; Index++)
  2. {
  3.    mythumbs[Index] = Image.FromFile(ThumbnailPathList[Index]);
  4. }
Am I close?
Nov 24 '09 #3
HaLo2FrEeEk
404 256MB
Here is the entire process from parsing all the <item>'s out of the XML up to the end of the foreach loop, which includes loading the bitmap.

Expand|Select|Wrap|Line Numbers
  1. XmlNodeList items = xdoc.GetElementsByTagName("item");
  2.                 overallProgress.Maximum = items.Count;
  3.                 foreach (XmlElement item in items)
  4.                 {
  5.                     XmlNodeList child = item.ChildNodes;
  6.                     string title = child[0].InnerText.ToString();
  7.                     string date = child[2].InnerText.ToString();
  8.                     string full = child[6].InnerText.ToString();
  9.                     string thumb = child[8].InnerText.ToString();
  10.                     string description = child[9].InnerText.ToString();
  11.                     //ThreadPool.QueueUserWorkItem(downloadThumb, thumb);
  12.                     Thread t = new Thread(downloadThumb);
  13.                     t.Start(thumb);
  14.                     t.Join();
  15.                     downloadThumb(thumb);
  16.                     Uri parts = new Uri(thumb);
  17.                     string query = parts.Query;
  18.                     string filename = query.Replace("?ssid=", "");
  19.                     DataGridViewRow newRow = new DataGridViewRow();
  20.                     newRow.Height = 90;
  21.                     DataGridViewImageCell thumbCell = new DataGridViewImageCell();
  22.                     DataGridViewCheckBoxCell downloadCell = new DataGridViewCheckBoxCell();
  23.                     thumbCell.Value = new Bitmap("./thumbs/" + filename + "-Thumbnail.jpg");
  24.                     downloadCell.Value = true;
  25.                     newRow.Cells.Add(downloadCell);
  26.                     newRow.Cells.Add(thumbCell);
  27.                     dataGridView1.Rows.Add(newRow);
  28.                     downloadCell.Selected = true;
  29.                     overallProgress.PerformStep();
  30.                 }
You can see I'm loading the bitmap like this:

thumbCell.Value = new Bitmap("./thumbs/" + filename + "-Thumbnail.jpg");

So disposing of the dataGridView should do the trick.
Nov 24 '09 #4
GaryTexmo
1,501 Expert 1GB
Out of curiosity, are you trying to access the file somewhere else in your program, or is the file access getting left open after you've closed it?

If you want to close the file handle, you can read the file into a memory stream, close the file, and load the image from the memory stream. Of course, this means you'll have all your images loaded into memory (can get big if your images are large), but you won't have the open file handle.

Also, just a heads up, if you close the memory stream on an animated bitmap you'll throw a GDI+ exception.
Nov 24 '09 #5
HaLo2FrEeEk
404 256MB
The images are all .jpg, and together all 30 add up to maybe 90 KB, so the size isn't an issue. So I would want to load the files into a memory stream inside the foreach loop then use that memory stream inside my new Bitmap() declaration instead of using the filename? How do I close the file once I've gotten it loaded into a memory stream? This might actually be the answer to my problem, I'm already downloading the file from the internet, maybe I'll just use the memory stream I get from the downloaded file as my new bitmap instead of writing it to a file...
Nov 24 '09 #6
Plater
7,872 Expert 4TB
Yup:
new Bitmap("./thumbs/" + filename + "-Thumbnail.jpg");
As long as that image object is alive, that file is in use.
Nov 24 '09 #7
GaryTexmo
1,501 Expert 1GB
For the purposes of this discussion, I'll submit some code I wrote a while back exploring exactly this issue.

http://members.shaw.ca/gtexmo/Code/C...PictureViewer/

There's a switch statement in there with the code for how I'm loading the image. Basically, I open the file, read it into a byte array, then close the file. After that I read that memory stream into an image object and go from there. I do not close the memory stream so as to avoid the GDI+ exception.
Nov 24 '09 #8
HaLo2FrEeEk
404 256MB
Ok, I managed to make the downloadThumb method return a memorystream that I then use for my Bitmap() object. Here is my full code:

Expand|Select|Wrap|Line Numbers
  1. using System;
  2. using System.IO;
  3. using System.Net;
  4. using System.Xml;
  5. using System.Drawing;
  6. using System.Windows.Forms;
  7.  
  8. namespace WindowsFormsApplication1
  9. {
  10.     public partial class Form1 : Form
  11.     {
  12.         string screenshotXML;
  13.  
  14.         public Form1()
  15.         {
  16.             InitializeComponent();
  17.         }
  18.  
  19.         public MemoryStream downloadThumb(object Url)
  20.         {
  21.             MemoryStream thumbMem;
  22.             string url = Url.ToString();
  23.             Uri parts = new Uri(url);
  24.             string query = parts.Query;
  25.             HttpWebRequest thumbreq = (HttpWebRequest)WebRequest.Create(url);
  26.             HttpWebResponse thumbres = (HttpWebResponse)thumbreq.GetResponse();
  27.             BinaryReader thumb = new BinaryReader(thumbres.GetResponseStream());
  28.             byte[] thumbnail = thumb.ReadBytes((int)thumbres.ContentLength);
  29.             thumbMem = new MemoryStream(thumbnail);
  30.             thumb.Close();
  31.             thumbres.Close();
  32.             return thumbMem;
  33.         }
  34.  
  35.         public void getXml(string gamertag)
  36.         {
  37.             HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://www.bungie.net/stats/halo3/PlayerScreenshotsRss.ashx?gamertag=" + gamertag);
  38.             req.Method = "GET";
  39.             HttpWebResponse response = (HttpWebResponse)req.GetResponse();
  40.             if (response.Headers["Content-Type"] == "text/html")
  41.             {
  42.                 MessageBox.Show("This gamertag is not valid.");
  43.                 gamertagBox.Focus();
  44.                 gamertagBox.SelectAll();
  45.             }
  46.             else
  47.             {
  48.                 dataGridView1.Rows.Clear();
  49.                 StreamReader responseStream = new StreamReader(response.GetResponseStream());
  50.                 screenshotXML = responseStream.ReadToEnd();
  51.                 XmlDocument xdoc = new XmlDocument();
  52.                 xdoc.LoadXml(screenshotXML);
  53.                 XmlNodeList items = xdoc.GetElementsByTagName("item");
  54.                 overallProgress.Maximum = items.Count;
  55.                 foreach (XmlElement item in items)
  56.                 {
  57.                     XmlNodeList child = item.ChildNodes;
  58.                     string title = child[0].InnerText.ToString();
  59.                     string date = child[2].InnerText.ToString();
  60.                     string full = child[6].InnerText.ToString();
  61.                     string thumb = child[8].InnerText.ToString();
  62.                     string description = child[9].InnerText.ToString();
  63.                     DataGridViewRow newRow = new DataGridViewRow();
  64.                     newRow.Height = 90;
  65.                     DataGridViewImageCell thumbCell = new DataGridViewImageCell();
  66.                     DataGridViewCheckBoxCell downloadCell = new DataGridViewCheckBoxCell();
  67.                     Bitmap thumbImg = new Bitmap(downloadThumb(thumb));
  68.                     thumbCell.Value = thumbImg;
  69.                     downloadCell.Value = true;
  70.                     newRow.Cells.Add(downloadCell);
  71.                     newRow.Cells.Add(thumbCell);
  72.                     dataGridView1.Rows.Add(newRow);
  73.                     downloadCell.Selected = true;
  74.                     overallProgress.PerformStep();
  75.                 }
  76.             }
  77.             dataGridView1.ClearSelection();
  78.             response.Close();
  79.         }
  80.  
  81.         private void getXML_Click(object sender, EventArgs e)
  82.         {
  83.  
  84.             string gamertag = gamertagBox.Text;
  85.             if (gamertag != "")
  86.             {
  87.                 getXml(gamertag);
  88.             }
  89.             else
  90.             {
  91.                 MessageBox.Show("You must enter a gamertag.");
  92.                 gamertagBox.Focus();
  93.             }
  94.         }
  95.     }
  96. }
See how on line 67 I'm using the downloadThumb(thumb) method inside the new Bitmap(). There must be a better way to do this...this seems so bloated.

And another thing, I liked how when I was using threading to run the downloadThumb thread each time a row was added to the dataGridView it automatically showed up, instead of waiting until the foreach loop finishes THEN showing the completely updated dataGridView box. Is there any way to do what I want here, with the downloadThumb method returning a memorystream, while running downloadThumb inside a thread?
Nov 25 '09 #9
Plater
7,872 Expert 4TB
Use the .Clone() function on the image.
Expand|Select|Wrap|Line Numbers
  1. Bitmap tempbm=new Bitmap("./thumbs/" + filename + "-Thumbnail.jpg"); 
  2. thumbCell.Value=tempbm.Clone();
  3. tempbm.Dispose();
  4.  
No muss, no fuss
Nov 25 '09 #10
HaLo2FrEeEk
404 256MB
Is there a way to run the downloadThumb method via a thread? I've found that the amount of memory used by the program for actually downloading the thumbnail files to a folder is more than he amount that I use when I just use a MemoryStream, so I'd like to stick with that, but how can I do a cross-thread access to the memory stream variable?
Nov 25 '09 #11
GaryTexmo
1,501 Expert 1GB
Could you start a thread that will download an image, then use a callback to return the image object which will then be put into wherever you want it to go? I don't know much about threading since I haven't used it much, but I'm pretty sure you can create a thread to do the work of generating the image itself, and then set up a callback to do something with that image when the thread is done.
Nov 25 '09 #12
HaLo2FrEeEk
404 256MB
I worded my message wrong. I've already got a method that will download the file from the supplied URL to either a file or a MemoryStream, the issue I'm having is that you can't share data between threads (at least I don't know a way to do it) so I need to get the MemoryStream (which is actually my preferred method over downloading to a file) from the method in one thread back into the main thread. Can I do that?
Nov 26 '09 #13
tlhintoq
3,525 Expert 2GB
Try to not pass the MemoryStream between threads. Instead have the downloading method raise an event when it is done, with the completed downloaded image as the argument of the event.

Have a method as the event handler for the "ImageDownloaded" event doing whatever you need it to do: SaveToHDD, ShowImage, AddToDataBase.

This should help separate the activities a little bit. Later when you find your next best way to download it isn't tightly integrated with the program flow; your new download method will still raise the event and the rest of the program will not know the difference.

In theory you could have several different methods that obtain an image in different ways yet all raise the same event: FTP, HTTP, FileCopy, FileSystemWatcher... anything that can recognize or obtain a new image can raise the event with the rest of the program being blissfully ignorant of the *how* and just worry about its own part after the fact.
Nov 26 '09 #14
HaLo2FrEeEk
404 256MB
I'm not sure I understand how to do this. I understand what you're saying, and what I need to do, I just don't know how. As much as I hate asking for help in this way, can you give me an example, in code, of what I should do.

In truth I've only been doing this for about 2 weeks total, so I'm still very new to C#.
Nov 26 '09 #15
GaryTexmo
1,501 Expert 1GB
Use the .Clone() function on the image.

Expand|Select|Wrap|Line Numbers
  1. Bitmap tempbm=new Bitmap("./thumbs/" + filename + "-Thumbnail.jpg"); 
  2. thumbCell.Value=tempbm.Clone();
  3. tempbm.Dispose();
No muss, no fuss
Did you give this a try? It definitely looks way slicker than what I have, so I tried implementing it... the file handle is still left open. There is a reason for this, it's intended behaviour by the Image class. The only way I've found to get around this is to load it into memory still...

Please let me know if this worked for you... if it did, I must be doing something wrong.
Nov 26 '09 #16
HaLo2FrEeEk
404 256MB
I didn't try it because I don't want to mess with files at all. Like I said, the program uses more memory when downloading the images to files than it does when I download it to a memorystream, so I'd rather use a memorystream.

I still need help with the example of tlhintoq's suggestion.
Nov 26 '09 #17
GaryTexmo
1,501 Expert 1GB
Oh sorry, I was talking to Platter in that particular message. I'm just wondering if he's doing something I'm not to make that work.
Nov 26 '09 #18
tlhintoq
3,525 Expert 2GB
I still need help with the example of tlhintoq's suggestion.
Frinny wrote a nice article on creating custom events:
http://bytes.com/topic/net/insights/...use-events-net

My own article on C# events can be found here:
http://bytes.com/topic/c-sharp/insig...ctical-example
Nov 28 '09 #19
Plater
7,872 Expert 4TB
(Since there no longer seems to be the ability to quote messages)
Gary: You're saying your file handle is kept open? The .Clone() method should not transfer the open file handle to the new image. But I will double check. I know I was doing the .Clone() to get rid of open file handles, but maybe I did something else to make it work
Nov 30 '09 #20
GaryTexmo
1,501 Expert 1GB
(I noticed that about the quoting thing too.... what happened?)

Yea, I used the code you had and it left the handle open for me. I tried nulling the object as well as disposing it and still the same.
Nov 30 '09 #21
Plater
7,872 Expert 4TB
Yea, I see that it keeps it open. My situation was a little different (involved Icon files) and seemed to work for that.

I just created this and it seemed to work?
Expand|Select|Wrap|Line Numbers
  1. private static Bitmap OpenBm(string location)
  2. {
  3.   Bitmap a = (Bitmap)Bitmap.FromFile(location);
  4.   Bitmap b = new Bitmap(a.Width, a.Height, a.PixelFormat);
  5.   b.SetResolution(a.HorizontalResolution, a.VerticalResolution);
  6.   //copy any other PropertyItems you may want?
  7.   Graphics gb = Graphics.FromImage(b);
  8.   gb.DrawImage(a, 0, 0);
  9.  
  10.   a.Dispose();
  11.   return b;
  12. }
  13.  
Nov 30 '09 #22
GaryTexmo
1,501 Expert 1GB
Hmmm ok. At that point I think one is as good as the other; the memory streams are working for me so I'll stick with that. Like I said before, I did some reading on the subject and Microsoft intends for this behaviour (though I feel like there should be an option built in).
Nov 30 '09 #23
tlhintoq
3,525 Expert 2GB
(Since there no longer seems to be the ability to quote messages)
(I noticed that about the quoting thing too.... what happened?)
Select text
Copy
Hit the quote balloon button
Paste
*Optionally assign a name to the quote inside the tag
Nov 30 '09 #24
Plater
7,872 Expert 4TB
Yes yes I know I can type [ quote ] and such, but there used to be a nice reply button
Dec 3 '09 #25
tlhintoq
3,525 Expert 2GB
I find it interesting that the quote link still exists in other forums such as the lounge:
http://bytes.com/forums/lounge/87789...nties-new-tech

That indicates that it still exists but has been SET to not be on in the various development forums such as this one. That is truly odd.
Dec 3 '09 #26
GaryTexmo
1,501 Expert 1GB
I noticed a bit of a change in the appearance of the forums lately and I seem to recall it happened about then. I wonder if a setting got missed in the changeover?

Ah, here's the answer... it was intended.
http://bytes.com/forums/feedback/878...-when-replying

But I guess they're looking at putting it back in (yay!).
Dec 3 '09 #27
tlhintoq
3,525 Expert 2GB
I add my vote/voice to having it back on.
Or maybe on for users>newbie
Dec 3 '09 #28

Sign in to post your reply or Sign up for a free account.

Similar topics

9
by: Paul | last post by:
Hi, VB.NET is saying the file I am creating is in use by another process and won't complete its task of moving the file to the specified destination folder. Here is my code (the main bit...
0
by: Tim | last post by:
Hi This is the problem: Read BLOB data from SQL Server. Create an image on the HD and assign it to a picture box. Works fine the first time. This is a usercontrol on a tab. When I close the tab...
5
by: Mike Dole | last post by:
When I am updating a picturebox with an image (extracted) from an access database I keep getting a "The process cannot access the file "c:\foto1.jpg because it is being used by another process"...
1
by: Jurgen Oerlemans | last post by:
Hello, I perform several actions on a file: * copy "xxx.txt" from directory 1 to "file.txt" directory 2 * process "file.txt" which is in directory 2 * delete the file in directory 1 .... and...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.