Click here to Skip to main content
15,917,005 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am writing program which reads data from csv file when file update. Now i got simple error i.e this "OnChanged" event fires two times as file update done one time.bellow is my code.

C#
  public void GetData()
        {
            try
            {
                //for (int i = 0; i >= 0; i++)
                //{
                    FileSystemWatcher watcher = new FileSystemWatcher();
                    watcher.Path = filepath;
                    watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
                   | NotifyFilters.FileName | NotifyFilters.DirectoryName;
                    // Only watch text files.
                    watcher.Filter = "*.csv";
                    watcher.Changed += new FileSystemEventHandler(OnChanged);
                   watcher.EnableRaisingEvents = true;
                //}
            }
            catch { }
        }

private void OnChanged(object source, FileSystemEventArgs e)
   {
       try
       {
           NetworkStream networkStream = clientSocket.GetStream();
           line = new string[] { };

           using(FileStream fs = new FileStream(e.FullPath,FileMode.Open,FileAccess.Read))
           using (StreamReader sr = new StreamReader(e.FullPath))
           {
              String [] line = sr.ReadLine().Split(',');
               for (int p = 0; p < line.Length; p++)
               {
                   b = Encoding.ASCII.GetBytes(line[p]);
                   networkStream.Write(b, 0, b.Length);
               }

               sr.Close();
               sr.Dispose();

               fs.Flush();
           }

       }
       catch { }
   }
Posted
Updated 5-Nov-15 19:33pm
v2

1 solution

As far as I know there is no way to avoid the file system watcher from firing multiple events, so I have used work-around to solve this issue.

You can try something like this. It is not foolproof if you have a lot of updates to multiple files. In that case you might have to use a list.
C#
private object lockObject = new object();
private string fileNameInUse = "";
private void OnChanged(object source, FileSystemEventArgs e)
{
    // Blocks the second call from being executed
    lock (lockObject)
    {
        if (fileNameInUse == e.FullPath) // This indicates that the file has already been handled.
        {
            fileNameInUse = "";
            return;
        }
        fileNameInUse = e.FullPath;

       try
       {
           NetworkStream networkStream = clientSocket.GetStream();
           line = new string[] { };
    
           using(FileStream fs = new FileStream(e.FullPath,FileMode.Open,FileAccess.Read))
           using (StreamReader sr = new StreamReader(e.FullPath))
           {
              String [] line = sr.ReadLine().Split(',');
               for (int p = 0; p < line.Length; p++)
               {
                   b = Encoding.ASCII.GetBytes(line[p]);
                   networkStream.Write(b, 0, b.Length);
               }
    
               sr.Close();
               sr.Dispose();
    
               fs.Flush();
           }
    
       }
       catch { }
    }
}

I hope I am wrong and there is a better solution.

[UPDATE]
An alternative solution
C#
private object lockObject = new object();
private void OnChanged(object source, FileSystemEventArgs e)
{
    // Temporary turn off raising new events
    watcher.EnableRaisingEvents = false;
    // Blocks the second call from being executed
    lock (lockObject)
    {
       try
       {
           NetworkStream networkStream = clientSocket.GetStream();
           line = new string[] { };
    
           using(FileStream fs = new FileStream(e.FullPath,FileMode.Open,FileAccess.Read))
           using (StreamReader sr = new StreamReader(e.FullPath))
           {
              String [] line = sr.ReadLine().Split(',');
               for (int p = 0; p < line.Length; p++)
               {
                   b = Encoding.ASCII.GetBytes(line[p]);
                   networkStream.Write(b, 0, b.Length);
               }
    
               sr.Close();
               sr.Dispose();
    
               fs.Flush();
           }
    
       }
        catch (Exception ex)  // It is always a bad idea to hide exceptions
        {
            MessageBox.Show(ex.ToString());
        }
        finally
        {
            // Restore raising events
            watcher.EnableRaisingEvents = true;
        }
    }
}
 
Share this answer
 
v2
Comments
Member 11543226 6-Nov-15 4:45am    
This works , but when file update again after few time it should again fire event. but it doesnt fires
George Jonsson 6-Nov-15 4:55am    
Do you mean that the OnChanged method is never entered?
What happens if you set a break point on this line?
Member 11543226 6-Nov-15 5:22am    
yes OnChange event never fires till application restarted. Break not hits.
George Jonsson 6-Nov-15 5:25am    
So if you use the debugger and set a break point it never reaches the break point?
That is kind of weird.
What is the value of fileNameInUse when the event has been fired?
Member 11543226 6-Nov-15 5:31am    
It fires at second execution also. but my string line [] not clears

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900