0

Currently i'm working on an application, that should watch a specific directory for changes (say a new file was created) and then in turn upload the file to Sharepoint. Thatfore i'm using the FileSystemWatcher class which throws an event with the path to the created file, which in turn i use in another method to upload the file. The problem is: While in debug mode in Visual Studio i realized that the first file i create in the watched directory gets uploaded perfectly, even if i drag multiple files into the directory at once all are uploaded, BUT when i do it one file after another i get an exception that the second file is already in use. So i drag File1.txt into the directory, it works, but then, when i drag file2.txt into the directory right after i get a System.IO.IOException while trying to create a filestream to upload to Sharepoint telling me that file2.txt is in use by another process.

The code for the FileSystemWatcher:

 public void StartWatcher()
        {
            FileSystemWatcher fsw = new FileSystemWatcher(this.path);

            fsw.IncludeSubdirectories = true;

            fsw.EnableRaisingEvents = true;



            fsw.Created += new FileSystemEventHandler(CreateFile);


            try
            {

                while (true)
                {
                    fsw.WaitForChanged(WatcherChangeTypes.All);
                }
            }
            catch
            { }

                fsw.EnableRaisingEvents = false;

        }

The CreateFile() method called by

fsw.Created += new FileSystemEventHandler(CreateFile);

looks like this:

 private void CreateFile(object sender, FileSystemEventArgs e)
        {
            path = String.Format(e.FullPath);
            filename = Path.GetFileName(path);
            Stream fs = File.OpenRead(@path);
            SPAPI spobj = new SPAPI();
            spobj.SPUploader(fs, filename);
            fs.Close();
        }

The exception is thrown at

Stream fs = File.OpenRead(@path);

BUT only when a second file is dragged into the directory after the first one. The strange thing is that not the first file is in use, but the second one that i want to open as a stream. So it's not the stream that is still open and causing the exception. It seems that the second file is in use by the FileSystemWatcher. But why does the first file work just fine but the exception is just thrown when a second file is dragged into the directory?

6
  • fsw.WaitForChanged(WatcherChangeTypes.All); - Ditch this. And that abomination of a loop around it including that empty catch. Commented Mar 29, 2018 at 8:46
  • 2
    File created event raise and trigger immediatly your CreateFile new file created into watched directory. However, you drag and drop file into directory does not mean you could use that file, because file probably still copying into directory. If your file size is standard and you know how much time require for copy/create operation, you can add Thread.Sleep() before path = String.Format(e.FullPath); Commented Mar 29, 2018 at 9:03
  • Give it some rest and try again. I've been successful with retrying 3 times after delaying 100ms each in the past. Commented Mar 29, 2018 at 9:05
  • It's an expected event. You should expect and handle it (if you got this error - wait a bit and try again). Commented Mar 29, 2018 at 9:09
  • 1
    @Mondblut note that Thread.Sleep(100) is not very reliable solution. Try to copy 1GB file to your folder and you'll see how it will fail with Thread.Sleep(100). Commented Mar 29, 2018 at 9:31

1 Answer 1

0

You can modify and use like this. I hope this helps you

private void CreateFile(object sender, FileSystemEventArgs e)
{
    int until = 5;
    int i = 0;
    bool success = false;
    while (!success && i < until)
    {
        try
        {
            path = String.Format(e.FullPath);
            filename = Path.GetFileName(path);
            using (Stream fs = File.OpenRead(@path);)
            {
                SPAPI spobj = new SPAPI();
                spobj.SPUploader(fs, filename);
            }
            success = true;
        }
        catch
        {
            i++;
            Thread.Sleep(TimeSpan.FromSeconds(1));
        }
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

This works like a charm, i just added fs.Close() to close the filestream.
Is there any advantage to just using Thread.Sleep(100) like some other users suggested?
Thread.Sleep(TimeSpan.FromSeconds(1)); or Thread.Sleep(TimeSpan.FromMilliseconds(1000)); or Thread.Sleep(1000) does not matter.
try-catch and until parameter gives some flexibility, if your files' size is different and large range. You can edit try count and wait time. For example: if file size is between 1x and 3x, you can use until=3 and waitResponse=t; if file size is between 2x and 8x, you can use until=4 and waitResponse = 2t. Result of this, task consume time according to file size.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.