VB.NET 中带有后台工作者的字幕进度条
Posted
技术标签:
【中文标题】VB.NET 中带有后台工作者的字幕进度条【英文标题】:Marquee Progress Bar with Background Worker in VB.NET 【发布时间】: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 执行的任何操作都将在不同的线程上执行,这意味着主窗体中的任何控件都不能从该线程修改。所以我建议你改为在按钮点击事件上调用进度条函数。
【参考方案1】:
您不能也不应该从您的“BigFunction()”访问您的 frmMainNew。它在一个单独的线程上工作,并且无权访问 UI 线程。我们需要看看你在你的 bigfunction 中做了什么来告诉你问题。我会猜测并说您正在尝试从该函数中更新进度条值?如果是这样,那么这样做的方法不正确。
您需要做的是,像这样在 BigFunction 中设置进度:
bgw.ReportProgress(Progress/Percentage)
并更改进度事件,在该事件内部是您更新进度条的地方。
Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
Progressbar1.value = e.ProgressPercentage
End Sub
【讨论】:
我认为我们不需要再看到任何东西了。它必须是进度条,因为在上面的任何代码中都没有调用它。 将w_ShowProgressBar()
调用移出 BigFunction 并移至 MyButton_Click()
。 :)
BigFunction 没有任何进度条或任何其他 UI 相关代码。这只是一个极其复杂的计算函数。我们正在添加一个进度条,因为它花费的时间太长并且屏幕在执行时会冻结。我会尝试这些建议。
你能解释一下这句话的意思吗--> “我在初始化时将表单作为参数传递给 MyClass 对象。” - 你的班级如何与表格互动?一旦 BigFunction 完成处理,结果会去哪里?您是否在 BigFunction 的类中使用其他对象/参数?您的 BigFunction 中是否还有代码来指示正在取得的进展?
该计算包含大量代码,涉及来自三种不同表单的大量信息以及主表单上的一些控件。因此,它有自己的类,我将 MainForm 作为参数传递给它的构造函数。但我明白你的意思。我在 MainForm 中编写了 ProgressChanged 事件。除非我这样做,否则如何从 MyClass 访问 bgw:ParentForm.bgw.ReportProgress(int)?
首先尝试找出为什么会弹出该错误。如有必要,逐行注释掉 myclass 中访问表单上任何元素的任何代码,然后从那里开始。以上是关于VB.NET 中带有后台工作者的字幕进度条的主要内容,如果未能解决你的问题,请参考以下文章