Harshit
Harshit

Reputation: 5157

The process cannot access the file because it is being used by another process. Unexpected error

I am using c# for FTP file upload using this code

while(true)
{
    if(condition == true)
    {
        Process[] proc = Process.GetProcessName("ThirdPartyApp");
        if(proc.Length <0 )
        {
            var file = Process.GetProcess().Where(pr=>pr.ProcessName == "ThirdPartyApp")
            foreach(var process in file)
            {
                process.kill(); // Third party application stopped
            }
            if(File.Exists(filename))
            {
               using (System.Net.WebClient client = new System.Net.WebClient())
               {
                 client.Credentials = new System.Net.NetworkCredential("username", "password");
                 client.UploadFile(ftpServer  + new FileInfo(filename).Name, "STOR", filename);
               }
               File.Delete(filename);
               Process.Start("ThirdPartyApp");
            }
       }
    }
}

My program continuously runs. At a specified time, it uploads a file to the server. After my program starts, it uploads the file successfully to the server at first time, but at another time interval, at the second time, it gives this exception.

I dont understand why it is giving error at the first loop run, but why it is giving error at the second time in loop.

The process cannot access the file 'E:\TYV.csv' because it is being used by another process.

After deleting the file, a new file immediately gets created. At the second run, which process is using that file? Is it my own application ?

Why it is not locked at the first time ?

Thanks

Upvotes: 0

Views: 3791

Answers (1)

Jauch
Jauch

Reputation: 1518

Changing the looping, as suggested in the comments, will not result if the file is locked. For sure your app is locking the file. This can mean that you are trying to upload the file before ts is released by the third party, or before the writing to it is finished (this can happen with buffered IO).

If you don't have access to the third party app to check what it is doing (and change it if necessary), you can do something like this:

This first routine checks if the file is locked (taken from here: Is there a way to check if a file is in use?

//routine to check if the file is locked
protected virtual bool IsFileLocked(FileInfo file)
{
    FileStream stream = null;

    try
    {
        stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
    }
    catch (IOException)
    {
        //the file is unavailable because it is:
        //still being written to
        //or being processed by another thread
        //or does not exist (has already been processed)
        return true;
    }
    finally
    {
        if (stream != null)
            stream.Close();
    }

    //file is not locked
    return false;
}

public void SendFile(string filename, int maxTries)
{
    bool done;
    while(true)
    {
        if(condition == true)
        {
            if(!IsFileLocked(filename))
            {
                Process[] processes = Process.GetProcessByName("ThirdPartyApp");
                foreach (var proc in processes)
                    proc.Kill();

                using (System.Net.WebClient client = new System.Net.WebClient())
                {
                    client.Credentials = new System.Net.NetworkCredential("username", "password");
                    int count = 0;
                    done = false;
                    while (count < maxTries || !done)
                    {
                        try
                        {
                            client.UploadFile(ftpServer  + new FileInfo(filename).Name, "STOR", filename);
                            done = true;
                        }
                        catch(Exception ex)
                        {
                            System.Threading.Thread.Sleep(5000);
                            count++;
                        }
                    }
                    if (!done)
                    {
                        //handle the error
                    }
                }

                File.Delete(filename);
                Process.Start("ThirdPartyApp");
            }
        }
    }
}

If it is a problem of a temporary locker, this can help you to solve it. But be warned that if you kill the third party before it releases the file, and the File.Exist can give you the false impression that the process finished it's job, you will still get a lock in the file.

Another point is the the Check to see if the file is locked can also fail, if just after the check the "ThirdPartyApp" locks the file and you kill the app before the app releases it.

So, to me the best answer is to use thsi code and try to open the file (locking it yourself). If this is possible (no exception), send to FTP using the opened stream.After finish, close it, delete the file and run the ThirdApp again.

EDIT: Add code to see if the file is locked and only if not delete the ThirdPartyApp and after this to execute the rest of the code.

Upvotes: 1

Related Questions