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

本文关键字:线程 错误 操作 控件 标签 | 更新日期: 2023-09-27 18:02:20

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

在我的表单控件上,我想向用户显示一个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();
        }

但是在下面一行出现错误:

跨线程操作无效:从a访问控制'lblTimer'非创建该线程的线程。

lblTimer.Text = name;

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

您已经测试了所需的调用,这是正确的,您只需要将导致错误的行移动到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'字符串。