次の方法で共有


FileSystemWatcher doesn't fire events for monitored network drive after changing InternalBufferSize

 

Problem and .NET Fix

Some customers have observed that a FileSystemWatcher monitoring a network drive fails to fire events after setting InternalBufferSize to certain values. The problem is that the value provided to InternalBufferSize is invalid and FileSystemWatcher attempts to notify your error handler when you enable raising events, but without an error handler you won't know about the problem.

The sample code below demonstrates this problem. If you uncomment the line that adds an error handler, then you'll get notification. Note that this is one of the many reasons it's important to add an error handler.

Unfortunately this particular failure is a bit more complicated than adding an error handler. In current releases, FileSystemWatcher has a bug in which it returns the wrong error if you request an invalid buffer size. Even if you add an error handler, ErrorEventArgs.GetException() will show this exception:

System.ComponentModel.Win32Exception: The operation completed successfully

But this is what you should see:

System.ComponentModel.Win32Exception: The supplied user buffer is not valid for the requested operation

We've already fixed this bug and the fix will appear in the next major runtime release. To clarify, with the fixed version, you will still get the exception in the error handler, but the exception message will be correct.

Workaround

With and without the runtime bug, setting the InternalBufferSize to 25 * 4096 is failing. To find a good buffer size, you can use the fact that, if your buffer size is valid, then it won't result in your error handler being called (i.e. it won't really get called to tell you the operation was successful). So you can experiment with buffer size; for example this succeeds for me:

watcher.InternalBufferSize = 4 * 4096;

You can try this out using the sample code below.

Sample Code

using System;
using System.IO;

class Repro
{

    static void Main()
    {

        // string networkDir = ???;
FileSystemWatcher watcher = new FileSystemWatcher(networkDir, "*.*");

        watcher.Created += OnCreated;

// uncomment out line below to add the error handler
// watcher.Error += OnError;
watcher.IncludeSubdirectories = true;

        watcher.InternalBufferSize = 25 * 4096;
// watcher.InternalBufferSize = 4 * 4096;

        watcher.NotifyFilter = NotifyFilters.FileName;

        watcher.EnableRaisingEvents = true;

        while (Console.ReadLine() != "x") { }
watcher.Dispose();

    }

    private static void OnCreated(object source, FileSystemEventArgs e)
{
Console.WriteLine("File: " + e.FullPath + " " + e.ChangeType);
}

    private static void OnError(object source, ErrorEventArgs e)
{
Console.WriteLine("Error!");
Console.WriteLine(e.GetException());
}

}

Comments

  • Anonymous
    April 27, 2008
    PingBack from http://microsoftnews.askpcdoc.com/io/filesystemwatcher-doesnt-fire-events-for-monitored-network-drive-after-changing-internalbuffersize

  • Anonymous
    May 07, 2008
    Ya gotta love those "lookup error zero" issues when they come up. Though I was curious about one thing. I assume this is meant to map to 1784 from winerror.h:    //    // MessageId: ERROR_INVALID_USER_BUFFER    //    // MessageText:    //    // The supplied user buffer is not valid for the requested operation.    //    #define ERROR_INVALID_USER_BUFFER        1784L So why the weird error code?

  • Anonymous
    May 07, 2008
    Sorry for the delay, we're not used to getting reader comments on this blog. :) You're right; that error code is suspicious. So I reran and I get the following, which is what I'd expect: System.ComponentModel.Win32Exception: The supplied user buffer is not valid for the requested operation I have no explanation for how that got in there. Perhaps it was a subconscious ploy to see if anyone's actually reading this... I'll update it, thanks!