窗口偶尔会在运行线程时挂起/冻结

时间:2013-01-16 15:38:55

标签: windows vb.net multithreading dispose invoke

我的VB.Net应用程序出现了一个奇怪的挂起问题。当用户单击更新按钮时,下面作为线程运行,以对数据进行一些长时间的计算。它禁用控件,显示“Working ...”文本框,完成工作,重新启用控件并删除“Working ...”文本框。偶尔(我从未在调试时再现),用户窗口冻结并挂起。当它发生时,CPU使用率为0,因此它完成了计算,但控件仍然显示为禁用,并且“工作...”文本框仍然可见,尽管窗口完全卡住并且不会更新。这将无限期地保持这种方式(用户已经尝试等待长达30分钟)。奇怪的是,我只能通过点击任务栏上窗口右键菜单中的最小化/恢复按钮来“解锁”窗口。经过短暂的延迟后,窗户恢复了生机。窗口本身的最小化/恢复似乎没有效果。

所以我的问题是,我在下面的帖子中做错了什么?

Dim Thread As New Threading.Thread(AddressOf SubDoPriceUpdateThread)
Thread.Start()

主题:

    Private Sub SubDoPriceUpdateThread()

            Dim Loading As New TextBox
            Try
                CntQuotePriceSummary1.Invoke(New Action(Of Control)(AddressOf CntQuotePriceSummary1.Controls.Add), Loading)
                CntQuotePriceSummary1.Invoke(New Action(Sub() CntQuotePriceSummary1.Enabled = False))

                Loading.Invoke(New Action(AddressOf Loading.BringToFront))
                Loading.Invoke(New Action(Sub() Loading.Text = "Working..."))

                '***Long running calculations***

                Invoke(New Action(AddressOf FillForm))

            Finally
                CntQuotePriceSummary1.Invoke(New Action(Of Control)(AddressOf CntQuotePriceSummary1.Controls.Remove), Loading)
                CntQuotePriceSummary1.Invoke(New Action(Sub() CntQuotePriceSummary1.Enabled = True))
                Loading.Invoke(New Action(AddressOf Loading.Dispose))
            End Try

    End Sub

1 个答案:

答案 0 :(得分:0)

根据Hans的评论,很清楚,在{i>}文本框中没有创建Loading文本框,这就是造成死锁问题的原因。我重写了代码。

     Private Sub SubDoPriceUpdateThread()

            Dim Loading As TextBox
            Invoke(Sub() Loading = New TextBox)

            Try
               Invoke(Sub()
                           CntQuotePriceSummary1.Controls.Add(Loading)
                           CntQuotePriceSummary1.Enabled = False
                           Loading.BringToFront()
                           Loading.Text = "Working..."
                       End Sub)

               '***Long running calculations***

                Invoke(Sub() FillForm())

            Finally
                Invoke(Sub()
                           CntQuotePriceSummary1.Controls.Remove(Loading)
                           CntQuotePriceSummary1.Enabled = True
                           Loading.Hide()
                           Loading.Dispose()
                       End Sub)
            End Try

    End Sub