【发布时间】:2015-02-20 10:06:27
【问题描述】:
我有一个主窗体,底部状态条有一个进度条。它设置为选取框样式。我希望它在何时保持动画 我运行一个很长的函数。但是当函数命中时,表单和它上面的所有东西都会冻结,所以我使用了一个后台工作程序 运行长功能。但这在 MyClass.BigFunction() 代码中给了我以下错误。
跨线程操作无效:控件“frmMainNew”从创建它的线程以外的线程访问。
“frmMainNew”是progressbar和backgroundworker所在的主窗体。我将表单作为参数传递给 MyClass 对象 当我初始化它时。
这是我第一次使用backgroundworker,我还需要什么? 我已经查看了这些示例并尝试了它们,但没有任何效果。 (1、2、3、4、5、6)。
我也必须将它用于其他功能。
我的代码:
Private WithEvents bgw As BackgroundWorker
Private Sub frmMainNew_Load(ByVal sender As Object, ByVal e As System.EventArgs) 处理 Me.Load
Try
Me.SuspendLayout()
'Other Functions
w_AddBackgroundWorkerForProgressBar()
Me.ResumeLayout()
Catch ex As Exception
Scube.Planner.ErrorHandler.DisplayError(ex)
End Try
End Sub
Private Sub w_AddBackgroundWorkerForProgressBar()
bgw = New BackgroundWorker
AddHandler bgw.DoWork, AddressOf bgw_DoWork
AddHandler bgw.RunWorkerCompleted, AddressOf bgw_Completed
'AddHandler bgw.ProgressChanged, AddressOf bgw_ProgressChanged
End Sub
Private Sub MyButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyButton.Click
Try
bgw.WorkerSupportsCancellation = True
bgw.RunWorkerAsync()
'MyClass.BigFunction() <--- Originally called from here
Catch ex As Exception
Scube.Planner.ErrorHandler.DisplayError(ex)
Finally
Me.Cursor = Cursors.Default
End Try
End Sub
Private Sub bgw_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles bgw.DoWork
'Do your lenghty operations here
MyClass.BigFunction()
System.Threading.Thread.Sleep(10000)
End Sub
Private Sub bgw_Completed(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) Handles bgw.RunWorkerCompleted
If Not IsNothing(e.Error) Then
MessageBoxEx.Show(e.Error.ToString)
End If
ProgressBar1.Hide()
End Sub
Private Sub w_ShowProgressBar()
ProgressBar1.Show()
Me.Refresh()
System.Windows.Forms.Application.DoEvents()
End Sub
【问题讨论】:
-
您必须从主窗体或其控件之一调用
w_ShowProgressBar()。如果它由 BackgroundWorker 或BigFunction()调用,它将不起作用,因为 BackgroundWorker 执行的任何操作都将在不同的线程上执行,这意味着主窗体中的任何控件都不能从该线程修改。所以我建议你改为在按钮点击事件上调用进度条函数。
标签: vb.net multithreading progress-bar