2

我的 VB.Net 应用程序有一个奇怪的挂起问题。当用户单击更新按钮时,以下内容作为线程运行以对数据进行一些长时间的计算。它禁用控件,显示“工作...”文本框,完成工作,重新启用控件并摆脱“工作...”文本框。有时(我在调试时从未复制过),用户窗口冻结并挂起。当它发生时,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
4

1 回答 1

0

根据 Hans 的评论,很明显Loading文本框不是在 UI 线程上创建的,这就是导致死锁问题的原因。我已经重写了代码。

     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
于 2013-01-18T20:35:14.390 回答