-1

I have tried several solutions with timers (tried all three timer classes) and none fire the Tick(elapsed) event in that specific spot. I have a multi-threaded WinForms application. What I need seems simple but I have spent days on this and ready to throw in the towel.

I need to display the live countdown in a pop up by second while an action is being executed. If 90 seconds pass with no results achieved (i have a flag), display warning, so I need to update the UI thread for sure.

I have looked into three different Timer classes and none work for me in that particular spot - their elapsed or tick events do not fire. I am thinking it's because I already have another thread that's polling the Serial Port because if I create a dummy button and tie the timer to the Click event, it's fine. Please note that I don't need the Timer to start inside the Serial Port polling, the functionality is totally separate.

Can someone suggest any solution that might work in this case?

Classes i tried are

 Windows.Forms.Timer
    System.Timers.Timer
    System.Threading.Timer
sarsnake
  • 26,667
  • 58
  • 180
  • 286
  • I've had good results with the `Stopwatch` class (`using System.Diagnostics;`). I have many state machines multi-threaded and I use the stop watch for a timeout and either re-issue a serial command if it timed out or do something else if max retries is met. Note that it doesn't have an event, you have to manually check the `ElapsedMilliseconds` to see if you timed out or not. But you can easily `Start`, `Stop`, and `Reset` the timer. See https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.stopwatch?view=netframework-4.8 – Baddack Oct 21 '19 at 22:14
  • Define *pop up*. If you show a Form with `SomeForm.Show(this)`, you have a child Window that can process `Timer.Tick` events without blocking the owner Window, which can proceed with its own processing. – Jimi Oct 22 '19 at 02:13
  • Unless you're blocking the UI thread while synchronously polling a SerialPort. Then nothing gets updated. – Jimi Oct 22 '19 at 02:28

1 Answers1

0

This answer assumes the "Popup" will not blocking the main UI Thread.

Create new MIDI child Form for your "Popup" if you want it to exist within the confines of the parent form otherwise this works fine.

Code taken from Alex's very helpful answer here: How to use a BackgroundWorker?

public Popup()
{
    InitializeComponent();

    backgroundWorker1.DoWork += backgroundWorker1_DoWork;
    backgroundWorker1.ProgressChanged += backgroundWorker1_ProgressChanged;
    backgroundWorker1.WorkerReportsProgress = true;
}

private void button1_Click(object sender, EventArgs e)
{
    backgroundWorker1.RunWorkerAsync();
}

private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
    for (int i = 0; i < 100; i++)
    {
        Thread.Sleep(1000);
        backgroundWorker1.ReportProgress(i);
    }
}

private void backgroundWorker1_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
{
    progressBar1.Value = e.ProgressPercentage;
    if(progressBar1.Value == 90) 
        WarningLbl.Text = "WARNING: Process is taking too long to complete.";
}
demoncrate
  • 390
  • 2
  • 14