我有一个奇怪的例外,我似乎无法调试。对于任何想要提出工作线程的人,我被禁止在我的工作中使用它们......我问为什么不是我自己,并收到一个模糊的答案和明确的指示,以避免它......反正......
我决定在一个单独的表单上有一个进度条,该表单已初始化并直接从我的库类中显示(独立于主表单并在不同的线程上执行)。即使这个类初始化表单本身,我仍然使用control.InvokeRequired和control.Invoke,所以我可以在其他地方重用该表单。 以下是初始化进度条:
Public Sub InitializePB(ByVal _Maximum As Integer, ByVal _Step As Integer, ByVal _StartValue As Integer, ByVal _Style As Windows.Forms.ProgressBarStyle)
If Me.InvokeRequired Then
'Different thread - invoke delegate
pb_Progress.Invoke(Sub() InitializePB(_Maximum, _Step, _StartValue, _Style))
Else
'Same thread - set values
pb_Progress.Minimum = 1
pb_Progress.Maximum = _Maximum
pb_Progress.Step = _Step
pb_Progress.Value = _StartValue
pb_Progress.Style = _Style
Me.Refresh()
End If
End Sub
现在为步骤功能:
Public Sub PerformStepPB()
If Me.InvokeRequired Then
'Different thread - invoke delegate
pb_Progress.Invoke(Sub() PerformStepPB())
Else
'Same thread - perform step
pb_Progress.PerformStep()
Me.Refresh()
End If
End Sub
现在,以下是我启动包含进度条的表单的测试代码,然后发送步骤调用:
pbForm = New frmProgress(_OwnerDesktopLoc)
pbForm.Show()
pbForm.InitializePB(100, 1, 1, Windows.Forms.ProgressBarStyle.Blocks)
Dim msElapsedVals As Integer = 0
While msElapsedVals <= 100
pbForm.PerformStepPB()
Thread.Sleep(100)
msElapsedVals += 1
End While
pbForm.Close()
pbForm.Dispose()
While Not pbForm.IsDisposed
Thread.Sleep(100)
End While
Exit Sub
到目前为止很好......你会注意到每次调用step方法时我都会调用进度条表单的Form.Refresh方法。我最终这样做是因为当表单启动时,它会在几个进度条步骤后崩溃。此时表单确实显示没有崩溃(因为刷新),除非我单击表单它崩溃(并且Visual Studio没有捕获异常)。奇怪的是,库类中用于更新进度条的代码继续没有任何问题,好像问题只是在Win32窗口中。以下是与崩溃相关的Windows消息:
说明 一个问题导致该程序停止与Windows交互。 问题签名: 问题事件名称:AppHangB1 应用程序名称:DL_RDS_Sort.vshost.exe
我尝试从主表单线程启动表单,但结果相同。我不知道发生了什么......任何帮助都会非常感激= D
更新确切的调用方式:
从MainForm开始,线程以库类中定义的子程序的地址开始:
Private Sub but_Sort_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles but_Sort.Click
Me.Sorter.OwnerDesktopLoc = New Drawing.Point(Me.DesktopLocation.X + CInt(Me.DesktopBounds.Width / 6), Me.DesktopLocation.Y + CInt(Me.DesktopBounds.Height / 2))
'Start sorting thread
Me.sortThread = New Threading.Thread(AddressOf Me.Sorter.Sort)
Me.sortThread.Start()
然后在这个线程的例程中,我正在测试表单的初始化并调用我为更新性能栏属性而编写的方法(如前所示):
Public Sub Sort()
Try
IIf(_OwnerDesktopLoc = Nothing, useProgressBar = False, useProgressBar = True)
'TESTING//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
pbForm = New frmProgress(_OwnerDesktopLoc)
pbForm.Show()
pbForm.InitializePB(100, 1, 1, Windows.Forms.ProgressBarStyle.Blocks)
Dim msElapsedVals As Integer = 0
While msElapsedVals <= 100
pbForm.PerformStepPB()
Thread.Sleep(100)
msElapsedVals += 1
End While
pbForm.Close()
pbForm.Dispose()
While Not pbForm.IsDisposed
Thread.Sleep(100)
End While
Exit Sub
'TESTING//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
请注意,测试区域后面有很多代码,但它永远不会被调用,并且在此问题中不起作用,因为我退出了子程序。我通常使用ShowDialog,但这会暂停执行,这不是我想要的。
值得一提的是: -frmProgress将ControlBox属性设置为false。 -frmProgress将FormBorderStyle设置为FixedDialog
另外:当我使用Show()方法时,当我将鼠标悬停在显示的表单上时,会出现Windows“忙碌圈”光标。 ShowDialog()没有这种行为......就好像表单正在等待某些东西......希望这能澄清我的问题。