Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

C#, FileSystemWatcher Closing App on Second Iteration

  1. Aug 6, 2010 #1
    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 (Text):
     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 (Text):
    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 (Text):
     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 (Text):
     public void button1_Click(object sender, EventArgs e)
            {
                FolderBrowserDialog fd = new FolderBrowserDialog();
                fd.ShowDialog();
                path = fd.SelectedPath;
                StartWatcher();
            }
     
  2. jcsd
  3. Aug 7, 2010 #2

    Mark44

    Staff: Mentor

    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().
     
  4. Aug 7, 2010 #3
    Something like ?

    Code (Text):
    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 seperate class file?
     
  5. Aug 7, 2010 #4

    Mark44

    Staff: Mentor

    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.
     
  6. Aug 7, 2010 #5
    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.
     
  7. Aug 8, 2010 #6

    Mark44

    Staff: Mentor

    I would start by putting a breakpoint in your OnChanged event handler, and also uncommenting the Console.WriteLine statement in that method.
     
  8. Aug 8, 2010 #7
    [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: Aug 8, 2010
  9. Aug 8, 2010 #8
    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.
     
  10. Aug 8, 2010 #9

    Mark44

    Staff: Mentor

    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.
     
  11. Aug 8, 2010 #10
    I would try:

    Code (Text):
    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: Aug 8, 2010
Share this great discussion with others via Reddit, Google+, Twitter, or Facebook