none
How can i display the timer count in seconds from a class to form1 ? RRS feed

  • Question

  • In the class top:

    System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();
    
            public class ProgressEventArgs : EventArgs
            {
                public int Percentage { get; set; }
                public string StateText { get; set; }
            }
    
            public event EventHandler<ProgressEventArgs> ProgressChanged;
    
            public void Init()
            {
                timer1.Interval = 30000;
                timer1.Stop();
                timer1.Tick += Timer1_Tick;
                object obj = null;
                int index = 0;
                ExtractCountires();
                foreach (string cc in countriescodes)
                {
                    // raise event here
                    ProgressChanged?.Invoke(obj,new ProgressEventArgs{ Percentage = 100 * index / countriescodes.Count, StateText = cc });
                    ExtractDateAndTime("http://www.sat24.com/image2.ashx?region=" + cc);
                    index +=1;
                }
                ImagesLinks();
            }

    Then the timer tick event

    private void Timer1_Tick(object sender, EventArgs e)
            {
                countriescodes = new List<string>();
                countriesnames = new List<string>();
                DatesAndTimes = new List<string>();
                imagesUrls = new List<string>();
                Init();
            }


    Then the method where i start the timer

    public void ExtractDateAndTime(string baseAddress)
            {
                try
                {
                    var wc = new WebClient();
                    wc.BaseAddress = baseAddress;
                    HtmlDocument doc = new HtmlDocument();
    
                    var temp = wc.DownloadData("/en");
                    doc.Load(new MemoryStream(temp));
    
                    var secTokenScript = doc.DocumentNode.Descendants()
                        .Where(e =>
                               String.Compare(e.Name, "script", true) == 0 &&
                               String.Compare(e.ParentNode.Name, "div", true) == 0 &&
                               e.InnerText.Length > 0 &&
                               e.InnerText.Trim().StartsWith("var region")
                              ).FirstOrDefault().InnerText;
                    var securityToken = secTokenScript;
                    securityToken = securityToken.Substring(0, securityToken.IndexOf("arrayImageTimes.push"));
                    securityToken = secTokenScript.Substring(securityToken.Length).Replace("arrayImageTimes.push('", "").Replace("')", "");
                    var dates = securityToken.Trim().Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
                    var scriptDates = dates.Select(x => new ScriptDate { DateString = x });
                    foreach (var date in scriptDates)
                    {
                        DatesAndTimes.Add(date.DateString);
                    }
                }
                catch(WebException wex)
                {
                    timer1.Start();
                }
            }


    And in form1

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
            {
                if (backgroundWorker1.CancellationPending == true)
                {
                    e.Cancel = true;
                    return; // this will fall to the finally and close everything    
                }
                else
                {
                    ei.ProgressChanged += (senders, eee) => backgroundWorker1.ReportProgress(eee.Percentage, eee.StateText);
                    ei.Init();
                }
            }
    
            private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
            {
                ProgressBar1.Value = e.ProgressPercentage;
                label7.Text = e.UserState.ToString();
                label8.Text = e.ProgressPercentage + "%";
            }
    
            private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
               if (e.Error == null)
                {
                    ProgressBar1.Value = 100;
                }
               else
                {
    
                }
            }

    Now it's reporting in form1 from the class Init() from inside the loop.

    But in case of exception i want that the timer tick event will raise after 30 seconds and will start over again the Init()

    But while it's waiting 30 seconds to start i want to report to the form1 a counter of 30 seconds.

    How can i use the event ProgressEventArgs to report the timer seconds to form1 label ?

    Saturday, December 31, 2016 5:15 PM

Answers

  • But in case of exception i want that the timer tick event will raise after 30 seconds and will start over again the Init()

    That goes into the area of proper exception handling, and it might be a poor path to take. I highly advise those two articles for people delvng into exception handling:
    Vexing exceptions - Fabulous Adventures In Coding - Site Home - MSDN Blogs

    Exception Handling Best Practices in .NET - CodeProject

    I think what you actually need is two timers:
    One to do the actuall work.
    One to trigger retries if something failed during the original work.

    And of course there should be a way to make no retries/0 wait between retries. After all the whole process might have to run automatically/unattended too. And in that case anything but just logging the exceptions and going on is not wanted.


    Remember to mark helpfull answers as helpfull and close threads by marking answers.

    • Marked as answer by Chocolade1972 Sunday, January 1, 2017 9:18 AM
    Sunday, January 1, 2017 6:33 AM

All replies

  • Hello Chocolade1972,

    The timer is set for 30 seconds only. If you want to display the value at every second, you'll need to set the timer to 1 second and then use a variable (maybe global) to count from 0 to 30, and then execute the code you want.

    Any other alternative (use current time snapshot and then do the diff, etc.) is overkill.

    Cheers.


    André Melancia | Developer / DBA / Microsoft Certified Trainer (MCT) | Andy.PT

    Saturday, December 31, 2016 11:52 PM
  • But in case of exception i want that the timer tick event will raise after 30 seconds and will start over again the Init()

    That goes into the area of proper exception handling, and it might be a poor path to take. I highly advise those two articles for people delvng into exception handling:
    Vexing exceptions - Fabulous Adventures In Coding - Site Home - MSDN Blogs

    Exception Handling Best Practices in .NET - CodeProject

    I think what you actually need is two timers:
    One to do the actuall work.
    One to trigger retries if something failed during the original work.

    And of course there should be a way to make no retries/0 wait between retries. After all the whole process might have to run automatically/unattended too. And in that case anything but just logging the exceptions and going on is not wanted.


    Remember to mark helpfull answers as helpfull and close threads by marking answers.

    • Marked as answer by Chocolade1972 Sunday, January 1, 2017 9:18 AM
    Sunday, January 1, 2017 6:33 AM