尝试为标签控件赋值时出现跨线程操作错误[重复]

Posted

技术标签:

【中文标题】尝试为标签控件赋值时出现跨线程操作错误[重复]【英文标题】:Getting cross thread operation error when trying to assign value to label control [duplicate] 【发布时间】:2016-12-19 11:46:48 【问题描述】:

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

因此,在我的表单控件上,我想向用户显示timer/stop watch,如下所示,start when my long running method will be called 并且我想在表单上以以下格式显示计时器,一旦方法为start or stopped,它将继续运行。

时:分:秒

代码:

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

但在下面一行出现错误:

跨线程操作无效:控件“lblTimer”从 线程不是创建它的线程。

lblTimer.Text = name;

我是 winform 的新手。

【问题讨论】:

@Lew:我已经搜索过这个问题,但没有得到您提供的链接。非常感谢您提供的链接 【参考方案1】:

您已经测试了所需的调用是否正确,您只需将导致错误的行移到 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();

【讨论】:

这工作正常。当我使用 system.windows.forms 的计时器控制时,为什么计时器滴答事件不会触发。这是否与跨线程操作一样的问题?? 这将取决于很多变量,如果没有示例抱歉,无法帮助您。不过更新您的原始问题或发布一个新问题,因为这听起来像是现在正在寻找新的东西!【参考方案2】:

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

【讨论】:

以上是关于尝试为标签控件赋值时出现跨线程操作错误[重复]的主要内容,如果未能解决你的问题,请参考以下文章

访问静态文件时出现跨域请求错误

发出 HTTP 请求时出现跨域错误

从 html 调用本地节点服务时出现跨源错误

将应用程序移动到子域时出现跨域安全错误 (2018)

为 vue-cli 运行“npm run dev”时出现跨环境问题

使用 .getJSON 获取 Play 商店应用详细信息时出现跨域阻止请求 [CORS] 错误