How can I prevent the file being used by another process exception?

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Michiel
    New Member
    • Jan 2011
    • 1

    #1

    How can I prevent the file being used by another process exception?

    Hi,

    I have a slight problem. What my application is supose to do, is to watch a folder for any newly copied file with the extention '.XSD' open the file and assign the lines to an array. After that the data from the array should be inserted into a MySQL database, then move the used file to another folder if it's done.

    The problem is that the application works fine with the first file, but as soon as the next file is copied to the folder I get this exception for example: 'The process cannot access the file 'C:\inetpub\adm ission\file2.XP D' because it is being used by another process'.

    If two files on the onther hand is copied at the same time there's no problem at all.

    The following code is on the main window:

    Code:
    namespace PatientPortal
    {
        public partial class Form1 : Form
        {
            static string folder = @"C:\inetpub\admission\";
            static FileProcessor processor;
    
            public Form1()
            {
                InitializeComponent();
                processor = new FileProcessor();
                InitializeWatcher();
            }
    
            static FileSystemWatcher watcher;
    
            static void InitializeWatcher()
            {
                watcher = new FileSystemWatcher();
                watcher.Path = folder;
    
                watcher.Created += new FileSystemEventHandler(watcher_Created);
                watcher.EnableRaisingEvents = true;
                watcher.Filter = "*.XPD";
            }
    
            static void watcher_Created(object sender, FileSystemEventArgs e)
            {
                processor.QueueInput(e.FullPath);
            }
        }
    }
    As you can see the file's path is entered into a queue for processing which is on another class called FileProcessor:

    Code:
    namespace PatientPortal
    {
        class FileProcessor
        {
            private Queue<string> workQueue;
            private Thread workerThread;
            private EventWaitHandle waitHandle;
    
            public FileProcessor()
            {
                workQueue = new Queue<string>();
                waitHandle = new AutoResetEvent(true);
            }
    
            public void QueueInput(string filepath)
            {
                workQueue.Enqueue(filepath);
    
                if (workerThread == null)
                {
                    workerThread = new Thread(new ThreadStart(Work));
                    workerThread.Start();
                }
    
                else if (workerThread.ThreadState == ThreadState.WaitSleepJoin)
                {
                    waitHandle.Set();
                }
            }
    
            private void Work()
            {
                while (true)
                {
                    string filepath = RetrieveFile();
    
                    if (filepath != null)
                        ProcessFile(filepath);
                    else
                        waitHandle.WaitOne();
                }
            }
    
            private string RetrieveFile()
            {
                if (workQueue.Count > 0)
                    return workQueue.Dequeue();
                else
                    return null;
            }
    
            private void ProcessFile(string filepath)
            {
                string xName = Path.GetFileName(filepath);
                string fName = Path.GetFileNameWithoutExtension(filepath);
    
                string gfolder = @"C:\Medi\Patient Files\ps_Good\";
    
                string line;
                string[] itemArray = null;
                int i = 0;
    
                #region Declare Db variables
    
                //Variables created for each field in the database
    
                #endregion
    
                #region Populate array
    
                    using (FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                    {
                        using (StreamReader reader = new StreamReader(filepath))
                        {
                            itemArray = new string[75];
    
                            while (!reader.EndOfStream == true)
                            {
                                line = reader.ReadLine();
                                itemArray[i] = line;
                                i++;
                            }
                            reader.Close();
                            reader.Dispose();
                            i = 0;
                        }
                    }
    
    
                #endregion
    
                #region Assign Db variables
    
                //Variables are assigned values and formatted appropriately
    
                #endregion
    
                #region MySql Connection
    
    			//Connection is made to the mysql database and the variables are added.
    
                #endregion
    
                #region Test and Move file
    
                if (System.IO.File.Exists(gfolder + xName))
                {
                    System.IO.File.Delete(gfolder + xName);
                }
    
                Directory.Move(filepath, gfolder + xName);
    
                #endregion
    
            }
        }
    }
    Now the exception occurs in the Populate array region at the following line:

    using (FileStream fs = new FileStream(file path, FileMode.Open, FileAccess.Read , FileShare.ReadW rite))

    Any help would be awesome

    Tx
  • GaryTexmo
    Recognized Expert Top Contributor
    • Jul 2009
    • 1501

    #2
    Is there any way the process that is copying the files into the folder is hanging on to the handle?

    Could you use something like process monitor (tool you can download) to see what's holding access on the file?)

    I don't see how it would matter because you're using a different file, but you could maybe force a close on the file stream at the end of the using block...?

    Comment

    • Plater
      Recognized Expert Expert
      • Apr 2007
      • 7872

      #3
      As mentioned, Microsoft Tools has a free download of "Process Explorer" that can help with this.
      When you break on that exception, open up Process Explorer and do a file handle search for the file in question. It should tell you who has the file open.
      If it is just you, then you probably have an issue with re-entry somewhere, although your code looked pretty well crafted.

      Comment

      • Samuel Jones
        New Member
        • Jan 2011
        • 48

        #4
        Try closing the 'watcher', it sits there staring at the file, hence using it.

        A simple watcher.Close() or watcher.Dispose () should suffice.

        Look for the simple things... :)

        Comment

        Working...