none
Event method called twice RRS feed

  • Question

  • I have an event handler that watches the file system to let me know when a file has changed and how it was changed.  The event handler reports how it was changed to the screen.  The problem is that it gives me the report twice.  My guess is that two instances of the handler are being added to the event.  (Event += hander is being called twice).  How do I make sure this doesn't happen when I have no control over the event?

    I tried writing an extension method:

    public static bool IsRegistered(this FileSystemEventHandler handler, Delegate prospectiveHandler) { return handler != null && handler.GetInvocationList().Any(existingHandler => existingHandler == prospectiveHandler); }

    The problem is that the following line gives an error:

    FileWatcher.Changed.IsRegistered()

    Compiling (and Intellisense) say:
    The event 'FileSystemWatcher.Changed' can only appear on the left hand side of += or -=  

    From what I have researched, you can only perform checks like this inside the class that issues the event... so has Microsoft written code to do this automatically? (and something else is causing the double report/message)?  If not, how can I check if an external event has a handler already (in a way that is thread safe)?







    • Edited by primem0ver Thursday, May 21, 2020 10:21 PM
    Thursday, May 21, 2020 10:19 PM

Answers

  • Thanks for all the help.  I am sure all of your answers are helpful.  I am especially interested in your subclass Bonnie.  However, overcame the issue myself on Friday by using a dictionary that had specifics about the change as the key and the time as the value.  If the time was for the last change with the same key was under a certain threshold, the changes are ignored.
    • Marked as answer by primem0ver Thursday, May 28, 2020 4:48 AM
    Wednesday, May 27, 2020 3:26 AM

All replies

  • You can put a breakpoint at ‘Event += handler’ to check the behaviour, or execute ‘Event -= handler’ before ‘Event += handler’.

    But documentation for FileSistemWatcher admits multiple events for file operations.

    Friday, May 22, 2020 4:29 AM
  • Hi primem0ver,

    Thank you for posting here.

    I haven't encountered these problems, but I found some links about this problem.

    Please see if someone's reply is helpful to you.

    -event- can only appear on the left hand side of += or -=

    C#: Raising an inherited event

    Best Regards,

    Timon


    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.

    Friday, May 22, 2020 6:44 AM
  • A single file operation can generate multiple file change events. This is by design. There is nothing you can do to prevent this. Your code needs to handle that case. It depends on how much data is being written and how. For example some apps create a brand new file so this would trigger a create and one or more changes. Others will modify the file in place so that will be a series of changes. Whether there is 1 change event or multiple is completely up to the OS. If the file is large then it'll require multiple change events. If the changes are small then it might require just one.

    File system events are raised by the OS as they occur so it is important that your handler does not block the caller in any way. Additionally the file is still open and being used by the remote process when the event is raised so that pretty much means you cannot do anything in the event handler beyond a simple log event at best. Any other work, especially any requiring access to the underlying file, requires that you use a separate background thread that runs later. Even then the file still may be locked so you'll have to add some retry logic. The event handler should determine if the event is important and then notify the background worker to do the work later (a shared queue is generally the approach). If you only expect one event for changes then you'll need to use some heuristics to determine if this is a single write operations (from the other app) or a series of changes. You can use the timestamp but it isn't flawless. 

    I recommend you read the many articles online about how to deal with multiple events for a single change. I wrote a blog article years ago on how you might solve this as well if you're interested.


    Michael Taylor http://www.michaeltaylorp3.net

    Saturday, May 23, 2020 3:16 PM
    Moderator
  • Hi primem0ver, 

    I also wrote a blog post many years ago. My approach was to sub-class the FileSystemWatcher class and make a few improvements to it to deal with some of the issues with multiple file events. You can read it here: https://geek-goddess-bonnie.blogspot.com/2014/08/filesystemwatcher-improvements.html

    Hope it helps.

    ~~Bonnie DeWitt [C# MVP]

    http://geek-goddess-bonnie.blogspot.com

    Sunday, May 24, 2020 1:48 AM
    Moderator
  • Thanks for all the help.  I am sure all of your answers are helpful.  I am especially interested in your subclass Bonnie.  However, overcame the issue myself on Friday by using a dictionary that had specifics about the change as the key and the time as the value.  If the time was for the last change with the same key was under a certain threshold, the changes are ignored.
    • Marked as answer by primem0ver Thursday, May 28, 2020 4:48 AM
    Wednesday, May 27, 2020 3:26 AM
  • Glad you got it working, primem0ver!  The way you ended up implementing it is clever.

    Let me know if you end up using my subclass for anything.  =0)


    ~~Bonnie DeWitt [C# MVP]

    http://geek-goddess-bonnie.blogspot.com

    Wednesday, May 27, 2020 5:05 AM
    Moderator
  • Hi primem0ver,

    It seems that your problem has been solved. You can click "Mark as answer" under your own reply, so that it will help other members to find the solution quickly if they face a similar issue.

    Best Regards,

    Timon


    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.


    Wednesday, May 27, 2020 6:33 AM