-2

I am having 1 long running process which I am running on seperate thread and when this long running process is going on I want to show time like stop watch on my form control just to show that process is going on and user doesn't think that program is stuck or block.

So on my form control I want to show user a timer/stop watch like below which will start when my long running method will be called and I want to show timer on form in below format which will keep on running as soon as method is start or stopped.

Hours : Minutes : Seconds

Code:

private void btnBrowse_Click(object sender, EventArgs e)
        {
            this.Invoke(new delegateFileProgress(Progressbarcount), 0);
            OpenFileDialog openFileDialog = new OpenFileDialog();
            DialogResult dialog = openFileDialog.ShowDialog();
            if (dialog == DialogResult.OK)
            {
                Thread longRunningProcess = new Thread(() => LongRunningMethod(openFileDialog.FileName));
            }
        }

private void LongRunningMethod(string path)
        {
             stopwatch.Start();

           TimeSpan ts = stopwatch.Elapsed;
           string name = string.Format("{0}:{1}", Math.Floor(ts.TotalMinutes), ts.ToString("ss\\.ff"));
           if (lblTimer.InvokeRequired)
           {
               lblTimer.BeginInvoke(new MethodInvoker(delegate { name = string.Format("{0}:{1}", Math.Floor(ts.TotalMinutes), ts.ToString("ss\\.ff")); }));
           }

           lblTimer.Text = name; Error:Cross-thread operation not valid: Control 'lblTimer' accessed from a thread other than the thread it was created on.
             /*
             * Long running codes which takes 30 - 40 minutes
            */
            stopwatch.Stop();
        }

But getting error on below line:

Cross-thread operation not valid: Control 'lblTimer' accessed from a thread other than the thread it was created on.

lblTimer.Text = name;

I am pretty new in winform.

halfer
  • 19,824
  • 17
  • 99
  • 186
I Love Stackoverflow
  • 6,738
  • 20
  • 97
  • 216

2 Answers2

2

You've tested for the invoke required which is correct, you just need to move the line that is causing the error into the else part of the if as its still being ran which is shouldn't be if invoke is needed.

private void LongRunningMethod(string path) {
  stopwatch.Start();
  TimeSpan ts = stopwatch.Elapsed;
  string name = string.Format("{0}:{1}", Math.Floor(ts.TotalMinutes), ts.ToString("ss\\.ff"));
  if (lblTimer.InvokeRequired) {
    lblTimer.BeginInvoke(new MethodInvoker(delegate {
      lblTimer.Text = name; 
    }));
  } else {
    lblTimer.Text = name; 
  }
  stopwatch.Stop();
}
jbmintjb
  • 161
  • 1
  • 10
  • This is working fine.When i am using timer control of system.windows.forms then why does timer tick event doenst fires.Is this same problem like cross thread operation?? – I Love Stackoverflow Aug 12 '16 at 13:20
  • That would depend on a lot of variables, can't help you much there without an example sorry. Update your original question though or post a new one as this sounds like its wandering off now to something new! – jbmintjb Aug 12 '16 at 13:23
2

Put the statement that assigns lblTimer.Text in the Control.BeginInvoke call, not the assignment of the 'name' string.

LoekD
  • 11,402
  • 17
  • 27