4

I know this is a common question but I can't seem to get it right. I have a form that goes out to gmail and processes some emails. I want to have a timer on the form to count how long the action has been running for. So once a user click the "start import" button I want the timer to start and once the "finished" messagebox appears it should stop. Here is what I have so far

Right now, the timer is just stays at the default text of "00";

namespace Import
{
public partial class Form1 : Form
{
Timer timer;
public Form1()
{
                InitializeComponent();              

}

private void btn_Import_Click(object sender, EventArgs e)
{
timer = new Timer();
timer.Interval = (1000);
timer.Enabled = true;
timer.Start();
timer.Tick += new EventHandler(timer_Tick);

// code to import emails

MessageBox.Show("The import was finished");
 private void timer_Tick(object sender, EventArgs e)
        {

            if (sender == timer)
            {
                lblTimer.Text = GetTime();
            }
        }
        public string GetTime()
        {
            string TimeInString = "";            
            int min = DateTime.Now.Minute;
            int sec = DateTime.Now.Second;

            TimeInString = ":" + ((min < 10) ? "0" + min.ToString() : min.ToString());
            TimeInString += ":" + ((sec < 10) ? "0" + sec.ToString() : sec.ToString());
            return TimeInString;
        }
}
}
}
MaylorTaylor
  • 4,671
  • 16
  • 47
  • 76
  • 2
    you should use some `Stopwatch` to measure time instead of Timer. – King King Nov 13 '13 at 17:32
  • I have a stopwatch in the full code and when the MessageBox displays I have it printout the `stopwatch.Elapsed` time. But I want a running count on the form also. – MaylorTaylor Nov 13 '13 at 17:34
  • 3
    `GetTime` could be reduced to `return DateTime.Now.ToString("mm:ss");` – Austin Salonen Nov 13 '13 at 17:34
  • Is the gmail processing running in the UI thread, or did you start a `BackgroundWorker` (or something similar)? If it's running on the UI thread, then there's no way that the timer can update because the UI thread is busy processing. – Jim Mischel Nov 13 '13 at 17:38
  • Yea @JimMischel ...that's my problem :/ I've been trying to correct that issue for a day or so now. But I've never worked with multiple threads. Can you point me to a good tutorial? – MaylorTaylor Nov 13 '13 at 17:42
  • Look into [`BackgroundWorkers`](http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(v=vs.110).aspx) (the example code at MSDN might be a good enough tutorial for you) – Austin Salonen Nov 13 '13 at 17:51
  • possible duplicate of [Timer using label](http://stackoverflow.com/questions/19868503/timer-using-label) – Mark Hall Nov 13 '13 at 19:54

1 Answers1

8

This is just one of many ways to do it. Of course, I would do it on background worker but this is legit way to get what you want:

Timer timer;
Stopwatch sw;

public Form1()
{
            InitializeComponent();              

}

private void btn_Import_Click(object sender, EventArgs e)
{
    timer = new Timer();
    timer.Interval = (1000);
    timer.Tick += new EventHandler(timer_Tick);
    sw = new Stopwatch();
    timer.Start();
    sw.Start();

    // start processing emails

    // when finished 
    timer.Stop();
    sw.Stop();
    lblTime.text = "Completed in " + sw.Elapsed.Seconds.ToString() + "seconds"; 
}


private void timer_Tick(object sender, EventArgs e)
{
    lblTime.text = "Running for " + sw.Elapsed.Seconds.ToString() + "seconds";
    Application.DoEvents();
}   
T.S.
  • 18,195
  • 11
  • 58
  • 78
  • Or, here, `..."Running for " + sw.Elapsed.Seconds.ToString()...` just use `Elapsed` and format it for your liking – T.S. Oct 19 '17 at 18:07