none
FileSystemWatcher crashes in mscorlib when simultaneously monitoring the same files more than once RRS feed

  • Question

  • I have a very simple program based on the MSDN sample code for using FileSystemWatcher. The code creates 12 watchers for 6 different files, and then waits for file write notifications. The notification handler is an empty function. I have a second program that repeatedly writes to each of the six files. After running the file watching program repeatedly (1 to 20 times) I will typically get an unhandled exception in mscorlib with a one line call stack: 

    > mscorlib.dll!System.Threading._IOCompletionCallback.PerformIOCompletionCallback(uint errorCode, uint numBytes, System.Threading.NativeOverlapped* pOVERLAP) + 0x47 bytes

    The crash happens almost immediately after the FileSystemWatcher code is run, and whether it happens or not is more or less random. (This doesn't feel like a kernel level buffer overrun problem at all.)

    I'm running Windows 7 Ultimate SP1. The code is built with VS2012 and .NET 4.5. I have .NET Framework 4.5.1 installed with a Version string of "4.5.50938"

    This is the FileSystemWatcher code:

    using System;
    using System.IO;
    using System.Security.Permissions;

    public class Watcher
    {

        public static void Main()
        {
        Run();

        }

        [PermissionSet(SecurityAction.Demand, Name="FullTrust")]
        public static void Run()
        {
            FileSystemWatcher watcher = new FileSystemWatcher();
            FileSystemWatcher watcher1 = new FileSystemWatcher();
            FileSystemWatcher watcher2 = new FileSystemWatcher();
            FileSystemWatcher watcher3 = new FileSystemWatcher();
            FileSystemWatcher watcher4 = new FileSystemWatcher();
            FileSystemWatcher watcher5 = new FileSystemWatcher();
            FileSystemWatcher watcher6 = new FileSystemWatcher();
            FileSystemWatcher watcher7 = new FileSystemWatcher();
            FileSystemWatcher watcher8 = new FileSystemWatcher();
            FileSystemWatcher watcher9 = new FileSystemWatcher();
            FileSystemWatcher watcher10 = new FileSystemWatcher();
            FileSystemWatcher watcher11 = new FileSystemWatcher();

            watcher.Path  = @"C:\\filemonitortest\\1\\";
            watcher1.Path = @"C:\\filemonitortest\\2\\";
            watcher2.Path = @"C:\\filemonitortest\\3\\";
            watcher3.Path = @"C:\\filemonitortest\\4\\";
            watcher4.Path = @"C:\\filemonitortest\\5\\";
            watcher5.Path = @"C:\\filemonitortest\\6\\";

            watcher6.Path = @"C:\\filemonitortest\\1\\";
            watcher7.Path = @"C:\\filemonitortest\\2\\";
            watcher8.Path = @"C:\\filemonitortest\\3\\";
            watcher9.Path = @"C:\\filemonitortest\\4\\";
            watcher10.Path = @"C:\\filemonitortest\\5\\";
            watcher11.Path = @"C:\\filemonitortest\\6\\";

            watcher.NotifyFilter = NotifyFilters.LastWrite;
            watcher1.NotifyFilter = NotifyFilters.LastWrite;
            watcher2.NotifyFilter = NotifyFilters.LastWrite;
            watcher3.NotifyFilter = NotifyFilters.LastWrite;
            watcher4.NotifyFilter = NotifyFilters.LastWrite;
            watcher5.NotifyFilter = NotifyFilters.LastWrite;
            watcher6.NotifyFilter = NotifyFilters.LastWrite;
            watcher7.NotifyFilter = NotifyFilters.LastWrite;
            watcher8.NotifyFilter = NotifyFilters.LastWrite;
            watcher9.NotifyFilter = NotifyFilters.LastWrite;
            watcher10.NotifyFilter = NotifyFilters.LastWrite;
            watcher11.NotifyFilter = NotifyFilters.LastWrite;

            watcher.Filter = @"test1.txt";
            watcher1.Filter = @"test1.txt";
            watcher2.Filter = @"test1.txt";
            watcher3.Filter = @"test1.txt";
            watcher4.Filter = @"test1.txt";
            watcher5.Filter = @"test1.txt";
            watcher6.Filter = @"test1.txt";
            watcher7.Filter = @"test1.txt";
            watcher8.Filter = @"test1.txt";
            watcher9.Filter = @"test1.txt";
            watcher10.Filter = @"test1.txt";
            watcher11.Filter = @"test1.txt";

            watcher.Changed += new FileSystemEventHandler(OnChanged);
            watcher1.Changed += new FileSystemEventHandler(OnChanged);
            watcher2.Changed += new FileSystemEventHandler(OnChanged);
            watcher3.Changed += new FileSystemEventHandler(OnChanged);
            watcher4.Changed += new FileSystemEventHandler(OnChanged);
            watcher5.Changed += new FileSystemEventHandler(OnChanged);
            watcher6.Changed += new FileSystemEventHandler(OnChanged);
            watcher7.Changed += new FileSystemEventHandler(OnChanged);
            watcher8.Changed += new FileSystemEventHandler(OnChanged);
            watcher9.Changed += new FileSystemEventHandler(OnChanged);
            watcher10.Changed += new FileSystemEventHandler(OnChanged);
            watcher11.Changed += new FileSystemEventHandler(OnChanged);

            watcher.EnableRaisingEvents = true;
            watcher1.EnableRaisingEvents = true;
            watcher2.EnableRaisingEvents = true;
            watcher3.EnableRaisingEvents = true;
            watcher4.EnableRaisingEvents = true;
            watcher5.EnableRaisingEvents = true;
            watcher6.EnableRaisingEvents = true;
            watcher7.EnableRaisingEvents = true;
            watcher8.EnableRaisingEvents = true;
            watcher9.EnableRaisingEvents = true;
            watcher10.EnableRaisingEvents = true;
            watcher11.EnableRaisingEvents = true;

            while (true) { }
        }

        // Define the event handlers. 
        private static void OnChanged(object source, FileSystemEventArgs e)
        {
          // empty handler!
        }
    }

    This is the code for the process that writes to the text files:

                     

    using System;
    using System.IO;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;

    namespace filewriter
    {
        class Program
        {
            static void Main(string[] args)
            {


                 for( int i = 0; i < 100000; i++ )
                 {

                     FileStream f = new FileStream(@"C:\\filemonitortest\\1\\test1.txt", FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite);
                     FileStream f2 = new FileStream(@"C:\\filemonitortest\\2\\test1.txt", FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite);
                     FileStream f3 = new FileStream(@"C:\\filemonitortest\\3\\test1.txt", FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite);
                     FileStream f4 = new FileStream(@"C:\\filemonitortest\\4\\test1.txt", FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite);
                     FileStream f5 = new FileStream(@"C:\\filemonitortest\\5\\test1.txt", FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite);
                     FileStream f6 = new FileStream(@"C:\\filemonitortest\\6\\test1.txt", FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite);

    // write a short string to each file:

                     string stri = i.ToString();
                     byte[] bytes = new byte[stri.Length * sizeof(char)];
                     System.Buffer.BlockCopy(stri.ToCharArray(), 0, bytes, 0, bytes.Length);

                     f.Seek(0, 0);
                     f2.Seek(0, 0);
                     f3.Seek(0, 0);
                     f4.Seek(0, 0);
                     f5.Seek(0, 0);
                     f6.Seek(0, 0);

                     f.Write(bytes, 0, bytes.Length);
                     f2.Write(bytes, 0, bytes.Length);
                     f3.Write(bytes, 0, bytes.Length);
                     f4.Write(bytes, 0, bytes.Length);
                     f5.Write(bytes, 0, bytes.Length);
                     f6.Write(bytes, 0, bytes.Length);


                     f.Flush();
                     f2.Flush();
                     f3.Flush();
                     f4.Flush();
                     f5.Flush();
                     f6.Flush();
                     f.Close();
                     f2.Close();
                     f3.Close();
                     f4.Close();
                     f5.Close();
                     f6.Close();
                 }
            }
        }
    }

    -------------------

    Can anyone help me avoid the crash or tell me if this has been fixed in a later version of .NET or Visual Studio? I need two modules that will monitor the same files. The files will not be updated as frequently as in this example, but I do expect bursts of up to 100 (write only) notifications per second.


    • Edited by Peter_M_ Thursday, August 27, 2015 11:48 PM
    Thursday, August 27, 2015 11:46 PM

All replies

  • Just to let you know, I tried your code using VS 2015 on Windows 10. It works with no exceptions at all. I started the watcher process more than 20 times and even concurrently.

    Alon.


    אלון פליס http://codevalue.net

    Saturday, August 29, 2015 11:57 PM
  • Hi Peter_M_M,

    I tested your code, it works fine on my side, I am using win8.1 .net framework 4.5. I suggest you open windows Event Viewer to get more error information from the application event log.

    Best Regards,
    Li Wang

    Monday, August 31, 2015 1:49 AM
    Moderator