C#, FileSystemWatcher Closing App on Second Iteration

  • Context: C# 
  • Thread starter Thread starter judahs_lion
  • Start date Start date
  • Tags Tags
    App
Click For Summary

Discussion Overview

The discussion revolves around an issue with a FileSystemWatcher in C# that closes the application on the second iteration of file handling. Participants explore potential reasons for this behavior, focusing on the code implementation and event handling related to file changes.

Discussion Character

  • Technical explanation
  • Debate/contested

Main Points Raised

  • One participant describes the problem of the application closing on the second iteration when handling file changes with FileSystemWatcher.
  • Another participant suggests that the watcher variable is a local variable in StartWatcher(), which may lead to it being disposed of when the method exits, proposing it should be a class member instead.
  • A similar suggestion is made regarding the watcher variable, with a query about whether to create a separate class file for it.
  • One participant expresses uncertainty about the original poster's description of the issue, asking for clarification on whether the first event is handled correctly before the application closes.
  • Another participant recommends using the Visual Studio debugger or re-enabling console output statements to better understand when the OnChanged event handler is triggered.

Areas of Agreement / Disagreement

Participants do not reach a consensus on the cause of the application closing. Multiple viewpoints are presented regarding the handling of the watcher variable and the debugging approach.

Contextual Notes

There is an assumption that the FileSystemWatcher is correctly set up to monitor file changes, but the implications of local versus class member scope for the watcher variable remain unresolved.

judahs_lion
Messages
56
Reaction score
0
I have a FileSystemWatcher, that moves excel data to a database when ever an excel sheet is made. But it keeps closing on the second iteration, and I can't understand why. Can someone please help. Here is the code.

Code:
 private void StartWatcher()
        {
            // Create a new FileSystemWatcher and set its properties.
            FileSystemWatcher watcher = new FileSystemWatcher();
            watcher.Path = path;
            /* Watch for changes in LastAccess and LastWrite times, and 
               the renaming of files or directories. */
            watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
               | NotifyFilters.FileName | NotifyFilters.DirectoryName;
            // Only watch text files.
            watcher.Filter = "*.xls";

            // Add event handler.
            watcher.Created += new FileSystemEventHandler(OnChanged);

            // Begin watching.
            watcher.EnableRaisingEvents = true;
        }

Code:
private void OnChanged(object source, FileSystemEventArgs e)
        {
            // Specify what is done when a file is changed, created, or deleted.
            // Console.WriteLine("File: " + e.FullPath + " " + e.ChangeType);
            StreamWriter te = new StreamWriter("fileList.txt");
            te.WriteLine(e.FullPath.ToString());
            te.Close();
            CreateIncidents(mX, dX);

           // txtOutput.AppendText(e.Name);
        }

Code:
 void CreateIncidents(IncidentsObjectsDataContext crt, IncidentsObjectsDataContext art)
        {
            string addr, crx;
            StreamReader kt = new StreamReader("fileList.txt");
            string xl = kt.ReadLine();
            Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application();
            Microsoft.Office.Interop.Excel.Workbook workBook = app.Workbooks.Open(xl, 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
            Microsoft.Office.Interop.Excel.Worksheet workSheet = (Microsoft.Office.Interop.Excel.Worksheet)workBook.ActiveSheet;
            int index = 0;
            int rowIndex = 18;
            DateTime dt5 = DateTime.FromOADate(0.0);
            string temp5;

            while (((Microsoft.Office.Interop.Excel.Range)workSheet.Cells[rowIndex, 1]).Value2 != null)
            {
                temp5 = Convert.ToString(((Microsoft.Office.Interop.Excel.Range)workSheet.Cells[rowIndex, 1]).Value2);
                //Converts OADatetime to DateTime
                addr = Convert.ToString(((Microsoft.Office.Interop.Excel.Range)workSheet.Cells[rowIndex, 2]).Value2);
                crx = Convert.ToString(((Microsoft.Office.Interop.Excel.Range)workSheet.Cells[rowIndex, 3]).Value2);

                try
                {
                    Double rogue = ((Microsoft.Office.Interop.Excel.Range)workSheet.Cells[rowIndex, 5]).Value2;
                    dt5 = DateTime.FromOADate(Convert.ToDouble(rogue));

                    addr = addr.Replace("BLK", string.Empty).Replace("(", string.Empty).Replace(")", string.Empty);
                    crx = crx.Replace("BLK", string.Empty).Replace("(", string.Empty).Replace(")", string.Empty);

                    incident newInc = new incident();
                    newInc.Agency = Convert.ToString(((Microsoft.Office.Interop.Excel.Range)workSheet.Cells[rowIndex, 1]).Value2);
                    newInc.Intersection = addr + "& " + crx;
                    newInc.CallTime = dt5;
                    newInc.IncidentType = Convert.ToString(((Microsoft.Office.Interop.Excel.Range)workSheet.Cells[rowIndex, 6]).Value2);
                    dX.incidents.InsertOnSubmit(newInc);
                    dX.SubmitChanges();
                    index++;
                    rowIndex = 18 + index;
                }
                catch
                {
                    try
                    {
                        Double rogue = ((Microsoft.Office.Interop.Excel.Range)workSheet.Cells[rowIndex, 6]).Value2;
                        dt5 = DateTime.FromOADate(Convert.ToDouble(rogue)); joinedResp newJR = new joinedResp();
                        newJR.Agency = Convert.ToString(((Microsoft.Office.Interop.Excel.Range)workSheet.Cells[rowIndex, 1]).Value2);
                        newJR.Address = Convert.ToString(((Microsoft.Office.Interop.Excel.Range)workSheet.Cells[rowIndex, 2]).Value2);
                        newJR.CrossStreet = Convert.ToString(((Microsoft.Office.Interop.Excel.Range)workSheet.Cells[rowIndex, 3]).Value2);
                        newJR.IncidentType = Convert.ToString(((Microsoft.Office.Interop.Excel.Range)workSheet.Cells[rowIndex, 6]).Value2);
                        mX.joinedResps.InsertOnSubmit(newJR);
                        mX.SubmitChanges();
                        index++;
                        rowIndex = 18 + index;
                    }
                    catch
                    {
                        index++;
                        rowIndex = 18 + index;
                    }
                }
            }
          //  workBook = null;
          //  app = null;
          //  workBook.Close();
          //  app.Quit();
        }

Code:
 public void button1_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog fd = new FolderBrowserDialog();
            fd.ShowDialog();
            path = fd.SelectedPath;
            StartWatcher();
        }
 
Technology news on Phys.org
Your watcher variable in StartWatcher() is a local variable, meaning that it is allocated when StartWatcher is called, and "dies" when StartWatcher is exited. It seems to me that this variable should be a member of whatever class the StartWatcher method belongs to, rather than being a local variable in StartWatcher().
 
Mark44 said:
Your watcher variable in StartWatcher() is a local variable, meaning that it is allocated when StartWatcher is called, and "dies" when StartWatcher is exited. It seems to me that this variable should be a member of whatever class the StartWatcher method belongs to, rather than being a local variable in StartWatcher().

Something like ?

Code:
public void button1_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog fd = new FolderBrowserDialog();
            fd.ShowDialog();
            path = fd.SelectedPath;

           // StartWatcher();
            // Create a new FileSystemWatcher and set its properties.
            FileSystemWatcher watcher = new FileSystemWatcher();
            watcher.Path = path;
            /* Watch for changes in LastAccess and LastWrite times, and 
               the renaming of files or directories. */
            watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
               | NotifyFilters.FileName | NotifyFilters.DirectoryName;
            // Only watch text files.
            watcher.Filter = "*.xls";

            // Add event handler.
            watcher.Created += new FileSystemEventHandler(OnChanged);

            // Begin watching.
            watcher.EnableRaisingEvents = true;
        }

Or should I create a separate class file?
 
Well, that's not what I was thinking, but I think it might work. Did you try it out?

I'm not crystal clear on what you said in the first post
judahs_lion said:
But it keeps closing on the second iteration, and I can't understand why.
Does that mean things work correctly when the first event is raised (LastAccess or LastWrite changed), on when your OnChanged event handler is called the first time?

If you are familiar with the Visual Studio debugger, I would suggest using it. If you aren't, I would suggest adding back in the console output statements in OnChanged that you commented out, so you can at least know when this handler is being called.
 
Mark44 said:
Well, that's not what I was thinking, but I think it might work. Did you try it out?

I'm not crystal clear on what you said in the first post
Does that mean things work correctly when the first event is raised (LastAccess or LastWrite changed), on when your OnChanged event handler is called the first time?

If you are familiar with the Visual Studio debugger, I would suggest using it. If you aren't, I would suggest adding back in the console output statements in OnChanged that you commented out, so you can at least know when this handler is being called.

It does everything it is supposed to on the first raised event" xls file created".
When the next is created it closes out. I tried using debugger stepping through, very long process in winforms btw ;). But it never shows me where it closes out, it just does it.
 
I would start by putting a breakpoint in your OnChanged event handler, and also uncommenting the Console.WriteLine statement in that method.
 
[STRIKE]I believe you are using some kind of timer that need to repeated? In that circumstance, using a background thread, default timer from .net, or even windows server / windows scheduler would do the job.[/STRIKE]

I am not understanding your concern. Does it not function when button is clicked second time?
 
Last edited:
rootX said:
[STRIKE]I believe you are using some kind of timer that need to repeated? In that circumstance, using a background thread, default timer from .net, or even windows server / windows scheduler would do the job.[/STRIKE]

I am not understanding your concern. Does it not function when button is clicked second time?

Its not a timer or a button that has to be push more than once. I am using an event handler. The first event handles correctly, the next closes the application/form.
 
I still believe you should have a separate class that contains your StartWatcher() and OnChanged() methods, where watcher is a class member. That way, your watcher object would remain alive for the lifetime of your class instance, not just during the lifetime of an invocation of one of the methods watcher is declared in. In post 3, you moved your watcher instance from StartWatcher() to button1_Click(), so in that code, watcher is valid only during the time that button1_Click() is executing.

Sorry I can't give more specific hints - I don't have VS installed on my home computer, so am not able to test my advice.
 
  • #10
I would try:

Code:
FileSystemWatcher watcher = new FileSystemWatcher();

public void button1_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog fd = new FolderBrowserDialog();
            fd.ShowDialog();
            path = fd.SelectedPath;

           // StartWatcher();
            // Create a new FileSystemWatcher and set its properties.
            
            watcher.Path = path;

Interesting though. I did not know about FileSystemWatcher class. I believe I had similar problem. I was using windows service that would check the file every interval and determine if new changes are made. If it finds new changes to the file, it would push them into db.

http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher.aspx says
"Note that a FileSystemWatcher does not raise an Error event when an event is missed or when the buffer size is exceeded, due to dependencies with the Windows operating system. To keep from missing events, follow these guidelines:" I think you also referred to it.
 
Last edited: