none
How to fix: The process cannot access the file because it is being used by another process. RRS feed

  • Question

  • I am attempting to transfer data from a specific folder to another in my local server, by looping through each file and use

    File.Move(sourceFile, DestinationFile)

    and below how my code is structured (only the code where the problem arises)

    using (SftpClient sftpClient = new SftpClient(host, username, password))
                            {
                                try
                                {
                                    //Connect to SFTP server
                                    foreach (var file in files)
                                    {
                                        if (!file.IsDirectory)
                                        {
                                            try
                                            {
                                                //Bunch of preprocessing
                                                    bool connected = sftpClient.IsConnected;
                                                    if (connected)
                                                    {
                                                        //Download files from remote server to local server
                                                        foreach (var item_db in files_path)
                                                        {
                                                            //Convert file from .db to .csv
                                                           
                                                        }
                                                        string subFolderCSV2 = Path.Combine(localDirectory, "CSV1");
                                                        using (var sftp_eagleio = new SftpClient(host_eagleio, username_eagleio, password_eagleio))
                                                        {
                                                            //Connect to Eagle.io server
                                                            foreach (var file_eagleio in files_eagleio)
                                                            {
                                                                string remoteFileName_eagleio = file_eagleio;
                                                                using (Stream file1_eagleio = new FileStream(remoteFileName_eagleio, FileMode.Open))
                                                                {
                                                                    //Transfer file from the local server to Eagle.io server on the cloud
                                                                }
                                                            }
                                                        }
                                                        sftpClient.Disconnect();
    
                                                        sftpClient.Connect();
    
                                                        if (removedb == "1")
                                                        {
                                                            sftpClient.DeleteFile(remotePath);
                                                            Console.WriteLine("File removed:" + remotePath);
                                                        }
                                                        else
                                                        {
                                                            sftpClient.RenameFile(remotePath, remoteUploadedPath);
                                                            Console.WriteLine("File moved to uploaded");
                                                        }
                                                        sftpClient.Disconnect(); 
                                                    }
    
                                            }
                                            catch (Exception er1)
                                            {
                                                //MessageBox.Show(er1.Message);
                                            }
                                        }
                                    }
                                }
                                catch (Exception entry)
                                {
                                    Console.WriteLine(entry.Message);
                                }
                                finally
                                {
                                    try
                                    {
                                        Console.WriteLine("Start");
                                        string[] LocalFileDir = Directory.GetFiles(sourcePath, "*.db"); 
                                        foreach (string f in LocalFileDir)
                                        {
                                            string fileName = Path.GetFileName(f);
                                            string destFile = Path.Combine(targetPath, fileName);
    
                                            if (removedownloaded == "1")
                                            {
                                                File.Delete(f);
                                                Console.WriteLine("File Deleted" + f);
                                            }
                                            else
                                            {
                                                File.Move(f, destFile);
                                                Console.WriteLine("File moved: " + f + "to " + destFile);
                                            }
                                        }
                                    }
                                    catch (Exception entry1)
                                    {
                                        Console.WriteLine(entry1.Message);
                                    }
                                    
                                    string[] LocalFileDirCSV = Directory.GetFiles(targetCSVPath, "*.csv");
    
                                    foreach (string fCSV in LocalFileDirCSV)
                                    {
                                        if (removecsv == "1")
                                        {
                                            File.Delete(fCSV);
                                           
                                            Console.WriteLine("File Deleted" + fCSV);
                                        }
                                        else
                                        {
                                            try
                                            {
                                                string fileNameCSV = Path.GetFileName(fCSV);
                                                string destFileCSV = Path.Combine(targetCSVPathAfterTransfer, fileNameCSV);
                                                File.Move(fCSV, destFileCSV);
                                                Console.WriteLine("File moved: " + fCSV + "to " + destFileCSV);
                                            }
                                            catch (Exception entry2)
                                            {
                                                Console.WriteLine(entry2.Message);
                                            }
                                        }
                                    }
                                }
                            }

    However, when It iterates through the data in this section of the code (in this case removedownloaded is zero so it go over File.Move(....)).

    ):

    if (removedownloaded == "1")
                                            {
                                                File.Delete(f);
                                                Console.WriteLine("File Deleted" + f);
                                            }
                                            else
                                            {
                                                File.Move(f, destFile);
                                                Console.WriteLine("File moved: " + f + "to " + destFile);
                                            }

    and before it complete the operation I receive this error on the last file: 

    A first chance exception of type 'System.IO.IOException' occurred in mscorlib.dll
    The process cannot access the file because it is being used by another process.

    I am not sure where it getting process somewhere else?

    Any idea how to solve this issue? I appreciate that


    Sami Arja


    • Edited by samiarja Friday, February 7, 2020 7:58 AM updated text
    Friday, February 7, 2020 7:55 AM

All replies

  • Hello,

    Seems like what is in the finally section should be refactored as this section is meant for cleaning up resources and here you are using this section for a completely different purpose.

    You could try implementing a retry on failure in the event there was not enough time for a handle to be released.

    const int numberOfRetries = 3;
    const int delayOnRetry = 1000;
    
    for (int index = 1; index <= numberOfRetries; ++index)
    {
        try
        {
            // Do stuff with file
            break;
        }
        catch (IOException exception) when (index <= numberOfRetries)
        {
            // You may check error code to filter some exceptions, not every error
            // can be recovered.
            Thread.Sleep(delayOnRetry);
        }
    }

    Or await rather than Sleep

    const int numberOfRetries = 3;
    const int delayOnRetry = 1000;
    
    for (int index = 1; index <= numberOfRetries; ++index)
    {
        try
        {
            // Do stuff with file
            break;
        }
        catch (IOException exception) when (index <= numberOfRetries)
        {
            // You may check error code to filter some exceptions, not every error
            // can be recovered.
            await Task.Delay(delayOnRetry);
        }
    }


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Friday, February 7, 2020 11:29 AM
    Moderator
  • I am not sure what the exact method is that is getting the error. Is it the File.Move method? if not then please clarify.

    Did you look at the InnerException? If there is one then it will provide more information.

    You can use Process Explorer - Windows Sysinternals and/or Handle - Windows Sysinternals to determine if another process has the file open. Probably not but it is good to be sure.

    I do not know what the SftpClient class is but if the error is for a local file then I assume the SftpClient class is not relevant.



    Sam Hobbs
    SimpleSamples.Info

    Friday, February 7, 2020 8:31 PM
  • Hi samiarja,

    Thank you for posting here.

    I noted that you used the keyword 'removedownloaded' in the code. However, I didn't see where it come from.

    Based on my test, if removedownloaded is a constant value, it will delete all the files which are text files or it will move all the files to other place.

    Therefore, please provide the code as possible as detailed.

    Best Regards,

    Jack


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, February 10, 2020 6:28 AM
    Moderator