Vb.net winform控件和线程

Vb.net winform控件和线程,vb.net,winforms,multithreading,Vb.net,Winforms,Multithreading,NET线程 我试图从backgroundworker.do_工作事件更新表单上的按钮文本,但失败了,出现了常见的跨线程异常消息 然而,纯属偶然,我还尝试从backgroundworker.do_工作事件更新system.windows.form.toolstripstatuslabel中的文本,它确实起作用 问:为什么会这样?这可能是因为system.windows.form.toolstripstatuslabel存在某种隐式共享行为吗 谢谢大家 为什么会这样 这纯属偶然。有时,它可能在其他人

NET线程

我试图从backgroundworker.do_工作事件更新表单上的按钮文本,但失败了,出现了常见的跨线程异常消息

然而,纯属偶然,我还尝试从backgroundworker.do_工作事件更新system.windows.form.toolstripstatuslabel中的文本,它确实起作用

问:为什么会这样?这可能是因为system.windows.form.toolstripstatuslabel存在某种隐式共享行为吗

谢谢大家

为什么会这样


这纯属偶然。有时,它可能在其他人身上起作用,但可能会崩溃。您不应该从没有创建GUI控件的线程(基本上是主GUI线程)更新任何GUI控件。

您如何创建/调用后台工作线程。你应该做一些像。。。(这是C#,不是VB)


然后,在后台工作程序的某个地方,只需调用ReportProgress()。。。该值几乎可以是任何值,即使表示百分比,例如ReportProgress(100)。这将强制直接回调窗体的线程(在UI线程上),让它更新需要的内容,然后返回后台工作程序继续。

关于
Windows窗体
需要记住的一个重要的泄漏抽象是,直到实际需要时才创建窗口
句柄。当您实例化表单时,不会创建句柄。相反,句柄是懒洋洋地创建的,只有在我们第一次得到Show()/ShowDialog()之类的调用时才有一个真正的窗口
hwnd
。例如,如果在工作线程完成中调用Show/showdillog,则在工作线程上创建句柄。在这里,直到作为工作线程完成其工作时发生的
invokererequired
(posting action asynch)检查的一部分对表单进行访问之前,从来没有人请求过表单的句柄。这可能是您偶尔会看到此问题的原因

这是ToolStripItem类的实现细节。它的行为类似于控件,但实际上不是从控件派生的。它是一个“无窗口”控件,使用其所有者的窗口绘制自身。更改Text属性会导致调用所有者的Invalidate()方法。这最终导致调用它的OnPaint方法并绘制项目。在UI线程上。Invalidate()是一个线程安全的方法,它只设置内部“此窗口需要绘制事件”状态位


虽然这确实避免了典型的UI线程问题,如死锁或彻底崩溃,但实际上它并不是完全线程安全的。可以在项目的paint方法运行的同时设置Text属性。最终显示的是未实际更新的可见文本。非常低的几率,不是零。

谢谢-但到目前为止,它一直有效,根本没有崩溃。@DoctorChrisChris-小心,这些东西有一个坏习惯,在开发环境中工作,然后在生产中崩溃!是的,我知道,非常感谢-我只是好奇为什么更新statuslabel.text时没有线程异常,但更新button.text时却有线程异常。
// This would be a method in your form...
private void CallBackgroundWorker()
{
   YourBackgroundWorkerClass BGW = new YourBackgroundWorkerClass();
   BGW.WorkerReportsProgress = true;
   BGW.ProgressChanged += MyFormsBGW_ProgressChanged;
   BGW.RunWorkerAsync();
}

// this would be in your form too... to get feedback from worker to 
// let the form's interface/control update itself
protected void MyFormsBGW_ProgressChanged(object sender, ProgressChangedEventArgs e)
{ 
   this.SomeButton.Text = "whatever";
}