I am writing a C# program that reads in a text file of a list of events followed by a date and time, delimited by a comma and prints it out to a textbox along with how much time is left till that date and time happens. It must read the data from a text file known as PersonalClock.dat (if there is data within it) or MasterClock.dat (if there is no data in PersonalClock.dat). However, I need it to update every 5 seconds. My code is below. Notice I have a function called pauseForMilliseconds (lines 31 and 50) that would cause the code to pause for 5 seconds. The way I have written it is that it will print out the list to the textbox, pause for 5 seconds, and then do it over again, infinite times until the close button is clicked. The problem is that instead of the window opening and the text appearing after 5 seconds (a test, not what I actually want it to do), the program waits 5 seconds before popping the application window open, in which the text is displayed instantly. It seems to me that the program does all its processing before it opens the window and then displays the results. I need it to display the results as soon as it gets the data and keep updating every 5 seconds. Any way to get the window to open first and then pause where needed? Any help is appreciated. P.S. I did try the timer class, but I've been having problems with it and adding it in there would require that I rewrite my code, which I don't want to do. Any help is appreciated.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
using System.Threading;

namespace EventClock
{
    public partial class eventClock : Form
    {
        public eventClock()
        {
            InitializeComponent();
            string line;

            StreamReader sr = new StreamReader("PersonalClock.dat");          // Create the StremReader object to read in from PersonalClock.dat.
            DateTime now = DateTime.Now;                                      // Create object to store the current date and time.

            line = sr.ReadLine();                                             // Read in the first line in the text file.
            if (line != null)                                                 // If the first line read in is not null...
            {
                displayText("PersonalClock.dat");                             // Display that PersonalClock.dat is being read in.
                //  while (true)
                //  {
                pauseForMilliseconds(5000);
                //System.Threading.Thread.Sleep(5000);
                line = sr.ReadLine();                                         // Read in the next line from the text file, as the first line can be ignored.
                while (line != null)                                          // While the line is not null...
                {
                    readAndProcess("PersonalClock.dat", ref line, now, sr);   // Call readAndProcess() to process each event.
                }
                //      resultsTextBox.Clear();
                //  }
            }
            else                                                              // if the first line read in from PersonalClock.dat was null...
            {
                displayText("MasterClock.dat");                               // Display that MasterClock.dat is being read in.
                StreamReader sr2 = new StreamReader("MasterClock.dat");       // Create the streamReader object to read in from MasterClock.dat.
                line = sr2.ReadLine();                                        // Read in first line.
                if (line != null)                                             // If the first line read in from MasterClock.dat was not null...
                {
                    while (true)
                    {
                        pauseForMilliseconds(5000);
                        line = sr2.ReadLine();                                    // Read in the next line because the first line can be ignored.
                        while (line != null)
                        {
                            readAndProcess("MasterClock.dat", ref line, now, sr2);    // Call readAndProcess() to process each event.
                        }
                        resultsTextBox.Clear();
                    }
                }
                else                                                          // If the first line read in from MasterClock.dat was null...
                {
                    resultsTextBox.Text = "Error. Both PersonalClock.dat and MasterClock.dat have no data.";   // Display that neither files had data.
                }
            }
        }

        private void exitButton_Click(object sender, EventArgs e)
        {
            this.Close();             // Close the application.
        }

        public void readAndProcess(string fileName, ref string line, DateTime now, StreamReader sr)
        {
            string[] eventDateTime = line.Split(',');                 // Separate the event name and the event datetime and store in a string array.
            string[] dateTime = eventDateTime[1].Split(' ');          // Separate the event datetime into the date and time and store in a string array.

            DateTime eventDate = DateTime.Parse(dateTime[1]);         // Parse the date and store it in a DateTime object.
            TimeSpan elapsedDays = eventDate.Subtract(now);           // Get the difference between the current date and the imported date and store in TimeSpan object.
            double daysAgo = elapsedDays.TotalDays;                   // Assign the difference to a double value.

            DateTime eventTime = DateTime.Parse(dateTime[2]);         // Parse the time and store it in a DateTime object.
            TimeSpan elapsedTime = eventTime.Subtract(now);           // Get the difference between the current time and the imported time and store in TimeSpan object.
            double hours = elapsedTime.Hours;                         // Capture the hours in a variable.
            double minutes = elapsedTime.Minutes;                     // Capture the minutes in a variable.
            double seconds = elapsedTime.Seconds;                     // Capture the seconds in a variable.

            if (dateTime[3] == "PM")                                  // If the "AM/PM" section that was parsed reads "PM"...
            {
                hours += 12;                                          // Add 12 to the hours.
            }

            string final = String.Format("{0,-20}{1,-24}{2,4}d{3,4}h{4,4}m{5,4}s",     // Create a string of all the data that needs to be output to the textbox.
                eventDateTime[0], eventDateTime[1], daysAgo.ToString("0"),
                hours.ToString(), minutes.ToString(), seconds.ToString());
            printToTextBox(final);                                    // Print the line to the textbox.
            line = sr.ReadLine();                                     // Read in the next line.
        }

        public void printToTextBox(string line)
        {
            resultsTextBox.Text += line + Environment.NewLine;     // Output the string to the textbox, using += so it does not override what's already there.
        }

        public void displayText(string text)
        {
            fileLabel.Text = "Displaying: " + text.ToString();     // Print out which file is being processed.
        }

        public void pauseForMilliseconds(int number)
        {
            Stopwatch sw = new Stopwatch();                            // stopwatch constructor.
            sw.Start();                                                // starts the stopwatch.
            for (int i = 0; ; i++)
            {
                if (i % 100000 == 0)                                   // if in 100000th iteration (could be any other large number 
                {                                                      // depending on how often you want the time to be checked) 
                    sw.Stop();                                         // stop the time measurement.
                    if (sw.ElapsedMilliseconds > number)               // check if desired period of time has elapsed.
                    {
                        break;                                         // if more than 5000 milliseconds have passed, stop looping and return                                            
                    }                                                  // to the existing code.
                    else
                    {
                        sw.Start();                                    // if less than 5000 milliseconds have elapsed, continue looping 
                    }                                                  // and resume time measurement.
                }
            }
        }
    }
}

Recommended Answers

All 3 Replies

Hi,

You had written your entire code in Constructor, Which says that, the code executes before the Form loads completely and your Pause function says that you are pausing the main thread, so that's why its taking 5 seconds time to load the Form and display the result. This looks like a monolithic Program, so you may not achieve your task in this pattern. Better option i suggest is to achieve your task is using threads.

1. Don't touch the Main Thread. Let the Form Load. After the Form Loads, Create an Another Thread Ans start the thread

2. Start the thread by calling the method where your methods read the data, and the display the test in Text Box and sleep the thread for every 5 seconds.

Hi,

You had written your entire code in Constructor, Which says that, the code executes before the Form loads completely and your Pause function says that you are pausing the main thread, so that's why its taking 5 seconds time to load the Form and display the result. This looks like a monolithic Program, so you may not achieve your task in this pattern. Better option i suggest is to achieve your task is using threads.

1. Don't touch the Main Thread. Let the Form Load. After the Form Loads, Create an Another Thread And start the thread

2. Start the thread by calling the method where your methods read the data, and the display the test in Text Box and sleep the thread for every 5 seconds.

I understand the concept, but due to being somewhat new with C#, how do I create a second thread? Is that the backgroundworker or is there a way to do it programmatically? Can you explain (with code examples) or submit a link that can show me?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.