尝试将值分配给标签控件时出现跨线程操作错误

Getting cross thread operation error when trying to assign value to label control

我有 1 个长 运行 进程,我在单独的线程上 运行,当这个长 运行 进程进行时,我想在我的秒表上显示时间表单控件只是为了显示进程正在进行并且用户不认为程序被卡住或阻塞。

所以在我的表单控件上,我想向用户显示如下所示的 timer/stop watch,这将 start when my long running method will be called 并且我想以下面的格式在表单上显示计时器,这将继续 运行只要方法是 start or stopped.

Hours : Minutes : Seconds

代码:

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();
        }

但在下一行出现错误:

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

lblTimer.Text = name;

我是 winform 的新手。

您已经测试了正确的调用要求,您只需将导致错误的行移动到 if 的 else 部分,因为它仍然是 运行,这是不应该的如果需要调用。

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();
}

将赋值lblTimer.Text的语句放在Control.BeginInvoke调用中,而不是'name'字符串的赋值。