Home > Net >  How do I notify the main form from a called filewatcher class on error?
How do I notify the main form from a called filewatcher class on error?

Time:08-18

I have a form that I'm calling a class that creates a filewatcher and does varies other things when the filewatcher fires. If an error occurs during the the filewatcher changed event, I need to let the main form know there was an issue.

My filewatcher class:

  internal static class PpsTransactionFileWatcher
  {
    private static FileSystemWatcher _watcher;

    public static Suburban.Miscellaneous.Response StartPpsFileWatcher()
    {
      var response = new Suburban.Miscellaneous.Response();
      response.IsSuccess = true;
      response.Message = "Success";

      try
      {
        CreateTrnFileWatcher();
        ProcessTransactionFile();
        return response;
      }
      catch (Exception ex)
      {
        LoggingWrapper.Log("StartPpsFileWatcher", ex.ToString(), ex);
        response.IsSuccess = false;
        response.Message = ex.Message;
        return response;
      }
    }

    private static void CreateTrnFileWatcher()
    {
      try
      {
        _watcher = new FileSystemWatcher
        {
          Path = GlobalSettings.PpsDirectory,
          NotifyFilter = NotifyFilters.LastWrite,
          Filter = GlobalSettings.PpsTransactionFile
        };

        _watcher.Changed  = TrnWatcherChanged;
        _watcher.EnableRaisingEvents = true;
      }
      catch (Exception ex)
      {
        LoggingWrapper.Log("CreateTrnFileWatcher", ex.ToString(), ex);
        throw;
      }
    }


    private static void TrnWatcherChanged(object sender, FileSystemEventArgs e)
    {
      try
      {
        _watcher.Changed -= TrnWatcherChanged;
        ProcessTransactionFile();
        _watcher.Changed  = TrnWatcherChanged;
      }
      catch (Exception ex)
      {
        LoggingWrapper.Log("TrnWatcherChanged", ex.ToString(), ex);
      }
    }
}

On my form, I'm calling it like this:

var transresponse = PpsTransactionFileWatcher.StartPpsFileWatcher();

How would I notify my form that there was an exception thrown from this class after it's started from the changed event?

CodePudding user response:

Perhaps an EventHandler would suit your needs here. Below is an example of an internal static class that has an EventHandler ErrorLogged defined.

You should be able to see how the event is subscribed to in the Program.Main.

For this particular console example, it loops in the background and may randomly generate errors based on a random number generator. It will relay the error number to any subscribers of the event.

The lines commented in all caps are the ones of particular relevance to your situation.

    class Program
    {
        internal static class ExampleEventManager
        {

            // the event handler here can send information to anything that subscribes to it
            // we make use of the empty delegate here to avoid any null errors when calling the event
            public static EventHandler<int> ErrorLogged = delegate { }; // THIS LINE DEFINES THE EVENT ITSELF WHICH WE WILL SUBSCRIBE TO           

            // a bool to control the loop for demonstration purposes
            private static bool ContinueRunning = true;

            // Starts the example
            public async static void Start()
            {


                Random rand = new Random();
                int errorCount = 0;

                // await a task here to make async
                await Task.Run(() => {

                    // run while our "continue running" flag is still true, and while we have encountered less than 10 errors
                    while (ContinueRunning)
                    {

                        // adds some delay to feel like "real time data and errors"
                        Task.Delay(100).Wait();

                        // randomly generate an error 10 in 100 chance (instead of 1 in 10, because we can show the slight differences in number generated for a more complete example)
                        int error = rand.Next(0, 100);
                        if (error > 89)
                        {
                            // notify the event which sends the information to any subscribers
                            ErrorLogged(null, error); // THIS LINE IS HOW YOU CALL THE EVENT FROM THE CLASS THAT THROWS THE ERROR

                            // increase the error count (for example)
                            errorCount  ;
                        }


                        // we exit if too many errors
                        if (errorCount >= 10)
                        {
                            Console.WriteLine("Too many errors encountered!");
                            break;
                        }

                    }

                    
                    Console.WriteLine("Example Stopped. Press any key exit program.");
                });
            }

            // stops the example
            public static void Stop()
            {
                ContinueRunning = false;
            }

        }

        static void Main(string[] args)
        {
            // subscribe to the event
            ExampleEventManager.ErrorLogged  = ExampleEventManagerExceptionThrown; // THIS LINE IS HOW YOU SUBSCRIBE TO THE EVENT

            Console.WriteLine("Starting Example...");

            ExampleEventManager.Start();

            Console.WriteLine("Example Started. Press any key to stop.");

            Console.ReadKey();

            ExampleEventManager.Stop();

            Console.ReadKey();
        }

        // This is Program writing to the console here
        static void ExampleEventManagerExceptionThrown(object sender, int eventParameter)
        {
            Console.WriteLine($"Error detected: {eventParameter}");
        }

  • Related