Click here to Skip to main content
15,867,330 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
See more:
hi guys,

Right now , I'm reading from a file and generating some statistics

the following is the code :



static FileSystemWatcher _watcher;

       static void Init()
       {
           //Adding a watcher to the following directory to know when there is a change.
           string directory = //path to directory";
           MainPage._watcher = new FileSystemWatcher(directory);
           MainPage._watcher.Changed += new FileSystemEventHandler(MainPage._watcher_Changed);
           MainPage._watcher.EnableRaisingEvents = true;

       }


       static void _watcher_Changed(object sender, FileSystemEventArgs e)
       {
           //reload MainPage to update statistics.

       }



       private void MainPage_Load(object sender, EventArgs e)
       {


           OperationClass oc = new OperationClass();
           oc.LoadFileForGenerationData();
           List<string> username = oc.gettingUserData();
           List<int> amountoftrn = oc.getAmountOfTrn();
           fillChart(username, amountoftrn);



           //LABELS
           List<int> counters = oc.LoadFileForNumberOfErrors();

           lblTotalNumberOfUsers.Text = username.Count().ToString();
           lblTotalNumberOfTrns.Text = amountoftrn.Sum(x => Convert.ToInt32(x)).ToString();

           lblErrors.Text = counters[0].ToString();
           lblFatals.Text = counters[1].ToString();
           lblWarnings.Text = counters[2].ToString();


           //filestreamWatcher
           Init();

       }



       private void fillChart(List<string> username, List<int> amountoftrn)
       {


           TransactionChart.Titles.Add("Transaction Chart");
           //                                                  //name of user , number of transactions
           int i = 0;
           foreach (var uname in username)
           {
               TransactionChart.Series["Transactions"].Points.AddXY(username[i], amountoftrn[i]);
               i++;
           }



       }



So i have a FileSystemWatcher on a directory so when there is a change in this directory i will reload the mainform so the _load method will run again and the statistics will be updated.
--------------------------------------------------------------
UPDATE:
I have made a new update thanks to lw@zi .
- Changed the filewatcher method to non-static
- made a method and put the _load content in it and called it from _changed and _load

The new problem is when i try to reload the statistics an IO exception is unhandled. this is the following code where the program is crashing (in the "using" line):
using (var filestream = new FileStream("//path to file.", FileMode.Open, FileAccess.Read,FileShare.None))
{
    MyTextFileDataSet.ContentExpression = new Regex(@"^(?<date>[^ ]+) (?<time>[^A-Z]+) (?<errorMessage>[^[]+) \[1\] (?<programName>[^.]+)[.](?<formName>[^.]+)[.](?<event>[^ ]+)[^a-z]+(?<username>[^:]+):(?<message>[^.]+).+$", RegexOptions.Multiline);

    MyTextFileDataSet.Fill(filestream);
    filestream.Flush();
    //filestream.Close();
    filestream.Dispose();
}

----------------------------------------------------------

If there is any problem or you did not understand do not hesitate to comment.

What I have tried:

I tried several methods to reload the MainPage (I got only 1 form.)

MainPage.ActiveForm.Dispose()
MainPage frm = new MainPage()
frm.Show()

---------
MainPage frm = new MainPage()
frm.refresh(), reload.....

when tried to dispose a nullreference excception was given.. Can someone tell me what can i do or maybe there is a workaround ?

-----------------------------------------------------------------
UPDATE OF WHAT HAVE YOU TRIED:
I tried to chnage the fileshare to ReadWrite but then a problem comes when i try to log with the log4net from another solution.
maybe it can help you, this is the app.config of the log4net.

<log4net>
    <root>
    <level value="DEBUG" />
    <appender-ref  ref="TestAppender" />
  </root>
  <appender name="TestAppender" type="log4net.Appender.RollingFileAppender">
    <lockingmodel type="log4net.Appender.FileAppender+MinimalLock"/>
    <param name="File" value="//same path of the filestream." />
    <param name="AppendToFile" value ="true"/>
    <encoding value="utf-8" />
    <rollingStyle value="Date" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date %level [%thread] %type.%method   %message%n" />
    </layout>
  </appender>

</log4net>

Someone can tell me what can i do ?
---------------------------------------------------
Posted
Updated 8-Aug-18 21:01pm
v2
Comments
FranzBe 8-Aug-18 8:48am    
There is no need to reload the whole form. You just need to update some data that is shown in the form. Make a private void ReloadStatistics() method, put the relevant code from the MainPage_Load event in it. Call the new method from MainPage_Load() as well as from _watcher_changed().
Joe Doe234 8-Aug-18 8:56am    
please see the comment of solution 1 , maybe you can help me please :)

I am not able to understand how you are using directory/file data. Perhaps operation class does that. In that case, if you can separate the code in load event handler and call that method from the event handlers for FileSystemWatcher.

Update:

There are few things which you should change in the code (without any knowledge of an alternate process working with same file).

1. In the constructor for FileStream, you are setting FileShare to None. This basically means that no other process can do anything with the file until this stream is closed. In your case, since you are only reading the file, I would suggest setting it to ReadWrite.
2. You are using using block. This means FileStream will be disposed off automatically as control goes out of the block. You do not need to call Dispose method.
3. You are also using Flush method which is again not needed since you are not writing to the file.

You can test your code after making the changes and see if everything works as expected.

As a side note, if you have any further question about a different issue, it would be better to post as another question to limit this one to current topic. For discussion style of working through a problem, IMHO, appropriate CP forum could be used.
 
Share this answer
 
v2
Comments
Joe Doe234 8-Aug-18 8:50am    
i tried that already but it won't let me as the method need to be static.
When i tried to put the method static it won't let me update the labels etc...

Maybe you can help me pleasE ? sorry for spamming
Joe Doe234 8-Aug-18 9:01am    
I tried what you told me and this is the error :
an object refence is required for that non-static field, method or proeprty 'MainPage.generatingStatistics()'

maybe i need to invoke the method ?? don't know just asking.
dan!sh 8-Aug-18 9:34am    
I see your event handlers for FileSystemWatchers are marked static. Any specific reason for that? You can remove static keyword from them.
Joe Doe234 9-Aug-18 1:41am    
hi sorry for the spamming, in one of my method i have this code :
public List<int> LoadFileForNumberOfErrors()        {            var MyTextFileDataSet = new TextFileDataSet.TextFileDataSet();            using (var filestream = new FileStream("//Path to file", FileMode.Open, FileAccess.Read,FileShare.None))            {                MyTextFileDataSet.ContentExpression = new Regex(@"^(?<date>[^ ]+) (?<time>[^A-Z]+) (?<errorMessage>[^[]+) \[1\] (?<programName>[^.]+)[.](?<formName>[^.]+)[.](?<event>[^ ]+)[^a-z]+(?<username>[^:]+):(?<message>[^.]+).+$", RegexOptions.Multiline);                MyTextFileDataSet.Fill(filestream);                filestream.Flush();                filestream.Dispose();            }


what can i do as when im trying to reload the statistics and IOException is unhandled, maybe you can help me please? as i already said sorry for spamming
dan!sh 9-Aug-18 2:37am    
Can you update the question with these details instead of comment section? It will be better for future readers.
perhaps you can use this as a starting point and work it out to your needs

public partial class Form1 : Form
 {
   private FileSystemWatcher _watcher;
   private System.Threading.Tasks.TaskScheduler _uiScheduler;
   public Form1()
   {
     InitializeComponent();
   }

   protected override void OnLoad(EventArgs e)
   {
     base.OnLoad(e);
     _uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
     InitFileSystemWatcher();
   }

   private void ReloadStatistics(FileSystemEventArgs e)
   {
     // use some sort of InvokeRequired here to update the Control in the UI-Thread
     Task.Factory.StartNew(() =>
     {
       string message = $"{DateTime.Now} : {e.Name}-{e.ChangeType}";
       label2.Text = message;
     }, CancellationToken.None, TaskCreationOptions.None, _uiScheduler);
   }

   private void InitFileSystemWatcher()
   {
     string directory = @"c:\temp"; //path to directory";
     _watcher = new FileSystemWatcher(directory);
     _watcher.Changed += new FileSystemEventHandler(OnWatcherChanged);
     _watcher.EnableRaisingEvents = true;
   }

   private void OnWatcherChanged(object sender, FileSystemEventArgs e)
   {
     ReloadStatistics(e);
   }
 }
 
Share this answer
 
Comments
Joe Doe234 9-Aug-18 1:36am    
hi thanks you for your solution , small question : what is the purpose of taskscheduler ?
FranzBe 9-Aug-18 4:38am    
The callback from the FileSystemWatcher does not run in the UI thread, so you can't update a control when you are in the OnWatcherChanged() method. There are various ways to deal with this (search for 'InvokeRequired') in the sample above I start a new task that runs in the UI thread, TaskScheduler.FromCurrentSynchronizationContext() takes care that the correct thread is used.
Joe Doe234 9-Aug-18 6:18am    
i will check it :) thank you very much :)

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