-1

I have a filesystemwatcher that checks files when a change happens. This runs fine 4 times in a row but on the 5th attempt that formwaitingform is not closed and the backgroundWorker1_RunWorkerCompleted is not called. I tried deleting the code that opens and closes the busy form and then the code runs as expected so it appears this is the issue.I am getting not error in my error trapping but suspect the issue to be related to filesystwatcher firing in a different thread and not having access to close the busy form but i am not sure. Any help appreciated.

    public partial class Main : Telerik.WinControls.UI.RadForm, IMessageFilter
    {

        WaitingForm formWaitingForm;
        BackgroundWorker bw = new BackgroundWorker(); // Backgroundworker
        public Main()
        {
......

public void OnChanged(object sender, FileSystemEventArgs e)
        {
            try
            {
                // Do not add logging before first line as we want to set the event change immediately to endure multiple events are not fired for 
                // multiple changes simultaneously


                if (MyGlobals.LastFired.Add(TimeSpan.FromSeconds(1)) < DateTime.UtcNow) //http://stackoverflow.com/questions/22236363/filesystemwatcher-for-a-list-of-files/22236688#22236688
                {
                    MyGlobals.LastFired = DateTime.UtcNow;
                    Logging.Write_To_Log_File("Entry", MethodBase.GetCurrentMethod().Name, "", "", "", "", "", "", 1); // See comment inside try
                    System.Threading.Thread.Sleep(2000);
                    Logging.Write_To_Log_File("Item change detected " + e.ChangeType + " " + e.FullPath + " " + e.Name, MethodBase.GetCurrentMethod().Name, "", "", "", "", "", "", 2);


                    MyGlobals.watchers.Clear();
                    foreach (FileSystemWatcher element in MyGlobals.watchers)
                    {
                        element.EnableRaisingEvents = false;
                    }
                    CheckFilesAsync(); // Get the timer to execute immediately

                }
                else
                {
                    Logging.Write_To_Log_File("Change within the time limit", MethodBase.GetCurrentMethod().Name, "", "", "", "", "", "", 1);
                }




                //Logging.Write_To_Log_File("Exit", MethodBase.GetCurrentMethod().Name, "", "", "", "", "", "", 1);
                return;

            }


            catch (Exception ex)
            {
                // If exception happens, it will be returned here
                Logging.Write_To_Log_File("Error", MethodBase.GetCurrentMethod().Name, "", "", ex.ToString(), "", "", "", 2);
            }

            finally
            {
                foreach (FileSystemWatcher element in MyGlobals.watchers)
                {
                    element.EnableRaisingEvents = true;
                }
            }


        }


 private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            try
            {
                Logging.Write_To_Log_File("Entry", MethodBase.GetCurrentMethod().Name, "", "", "", "", "", "", 1);
                lock (MyGlobals._object) // Lock for threadsafe operations
                {

                    // First, handle the case where an exception was thrown. 
                    if (e.Error != null)
                    {
                        RadMessageBox.Show(this, e.Error.Message, "Error", MessageBoxButtons.OK, RadMessageIcon.Error);
                        Logging.Write_To_Log_File(e.Error.Message, MethodBase.GetCurrentMethod().Name, "", "", "", "", "", "", 2);

                    }
                    else if (e.Cancelled)
                    {
                        // Next, handle the case where the user canceled the operation. 
                        RadMessageBox.Show(this, "Background task cancelled", "Cancel", MessageBoxButtons.OK, RadMessageIcon.Error);
                        Logging.Write_To_Log_File("Task cancelled", MethodBase.GetCurrentMethod().Name, "", "", "", "", "", "", 1);
                    }
                    else
                    {
                        // Finally, handle the case where the operation succeeded.

                        Logging.Write_To_Log_File("Finished background worker - closing Form", MethodBase.GetCurrentMethod().Name, "", "", "", "", "", "", 1);

                        this.BeginInvoke((MethodInvoker)(() => formWaitingForm.Close()));
                        this.BeginInvoke((MethodInvoker)(() => formWaitingForm.Dispose()));
                        //formWaitingForm.Close();
                        //formWaitingForm.Dispose();
                        Logging.Write_To_Log_File("Form closed", MethodBase.GetCurrentMethod().Name, "", "", "", "", "", "", 1);

                    }
                   // _timer.Enabled = true;
                }
                Logging.Write_To_Log_File("Exit", MethodBase.GetCurrentMethod().Name, "", "", "", "", "", "", 1);
            }
            catch (Exception ex)
            {
                // If exception happens, it will be returned here
                Logging.Write_To_Log_File("Error", MethodBase.GetCurrentMethod().Name, "", "", ex.ToString(), "", "", "", 2);
            }



        }
user1438082
  • 2,740
  • 10
  • 48
  • 82

1 Answers1

0

Filesystemwatchers raise events when files change - i want to trigger CheckFilesAsync which then opens a busy form and at the end closes this form. Calling Checkfilesasync in the main thread as shown below solves my issue.

   this.BeginInvoke((MethodInvoker)(() => CheckFilesAsync())); // Check files in the Main thread otherwise threading issues occur
user1438082
  • 2,740
  • 10
  • 48
  • 82