多线程循环冻结ui

时间:2016-01-13 13:31:35

标签: .net vb.net multithreading delegates thread-safety

我在应用程序中遇到了多线程编程问题。 实际上,代码看起来像这样:

Private Delegate Sub IniciarDiscagemDelegate()

Private Sub CallBack()
    'do some stuff....
    ThreadDiscagem = New Threading.Thread(AddressOf IniciarDiscagem)
    ThreadDiscagem.IsBackground = True
    ThreadDiscagem.Start()
End Sub

Private Sub IniciarDiscagem()
    If Me.InvokeRequired() Then
        Me.BeginInvoke(New IniciarDiscagemDelegate(AddressOf IniciarDiscagem))
        Exit Sub
    End If
    Do While True
       'This boolean is used to control navigation. I set false to it whenever the current entry is closed by the user.
       If Not blnEntryAlreadyOpen Then LookForNewEntries()
    Loop
End Sub

Private Sub LookForNewEntries()
    Dim blnFoundIt As Boolean = False
    Do While Not blnFoundIt
        blnFoundIt = DatabaseMethod()
    Loop
    'Some code that would change UI behavior, show some controls and hide others.
End Sub

Private Sub DataBaseMethod()
    'Code that looks for new entries at the DB
    return true
End Sub

虽然有可供使用的条目,但代码运行完美。用户界面运行正常,用户可以导航。问题是当没有可用的条目时,应用程序停留在" LookForNewEntries"循环并冻结整个UI。

不应该冻结UI,因为这个循环直接从不是主线程的线程运行吗?

无法找到解决此问题的方法,有人可以给我一个提示吗?

谢谢!

最好的问候。

1 个答案:

答案 0 :(得分:3)

事实上实际上是从主线程运行它。

这句话是你的问题:

If Me.InvokeRequired() Then
    Me.BeginInvoke(New IniciarDiscagemDelegate(AddressOf IniciarDiscagem))
    Exit Sub
End If

您正在调用您的方法,这将使其在主线程上运行。在您要修改主线程上的内容之前,您不应该使用调用。所以暂时删除那段代码。

例如,如果您要更改TextBox的文本,则需要调用。

.NET 4.0及更高版本的示例:

If Me.InvokeRequired Then
    Me.BeginInvoke(Sub() TextBox1.Text = "Done")
End If

.NET 3.5及更低版本的示例:

If Me.InvokeRequired Then
    Me.BeginInvoke(New IniciarDiscagemDelegate(AddressOf <method to perform changes here>))
End If