更新时,单独表单上的进度条会冻结/崩溃

时间:2012-05-11 22:22:40

标签: vb.net winforms progress-bar invokerequired

我有一个奇怪的例外,我似乎无法调试。对于任何想要提出工作线程的人,我被禁止在我的工作中使用它们......我问为什么不是我自己,并收到一个模糊的答案和明确的指示,以避免它......反正......

我决定在一个单独的表单上有一个进度条,该表单已初始化并直接从我的库类中显示(独立于主表单并在不同的线程上执行)。即使这个类初始化表单本身,我仍然使用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()没有这种行为......就好像表单正在等待某些东西......希望这能澄清我的问题。

0 个答案:

没有答案