C# IOException: The process cannot access the file because it is being used by another process.

Posted by Michiel Bester on Stack Overflow See other posts from Stack Overflow or by Michiel Bester
Published on 2011-01-06T23:42:11Z Indexed on 2011/01/06 23:54 UTC
Read the original article Hit count: 206

Filed under:
|

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\admission\file2.XPD' 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:

public partial class Form1 : Form
{
    static string folder = specified path;        
    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:

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 = specified path;            
        bool fileInUse = true;
        string line;
        string[] itemArray = null;
        int i = 0;


        #region Declare Db variables

        //variables for each field of the database is created here

        #endregion


        #region Populate array

        while (fileInUse == true)
        {
            FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read,           
                                           FileShare.ReadWrite);

            StreamReader reader = new StreamReader(fs);

            itemArray = new string[75];

            while (!reader.EndOfStream == true)
            {
                line = reader.ReadLine();
                itemArray[i] = line;
                i++;
            }
            fs.Flush();
            reader.Close();
            reader.Dispose();
            i = 0;
            fileInUse = false;
        }

        #endregion

        #region Assign Db variables

        //here all the variables get there values from the array

        #endregion

        #region MySql Connection

        //here the connection to mysql is made and the variables are inserted into the db

        #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

    }
}

The problem I get occurs in the Populate array region. I read alot of other threads and was lead to believe that by flushing the file stream would help...

I am also thinking of adding a try..catch for if the file process was successful, the file is moved to gfolder and if it failed, moved to bfolder

Any help would be awesome

Tx

© Stack Overflow or respective owner

Related posts about c#

Related posts about .NET