1

我有一个奇怪的异常,我似乎无法调试。对于任何要建议工作线程的人,我都被禁止在工作中使用它们......我问自己为什么不这样做,并收到一个模糊的答案和明确的指示来避免它......无论如何......

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

4

0 回答 0