新线程仍在阻止UI-Thread

时间:2009-07-17 11:57:46

标签: vb.net multithreading

当单击一个按钮时,我启动一个单独的thead,它是一个网格,并使用webbrowser-control做一些事情。但是当单击按钮时,新线程似乎不是单独的,导致UI冻结,直到新线程完成。

这里是代码:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click
    FindCustomerLocation()
    e.Handled = True
End Sub


Private Sub FindCustomerLocation()
    Dim Findcontractor_Thread As New Thread(AddressOf FindContractor_ThreadExecute)
    Findcontractor_Thread.Priority = ThreadPriority.AboveNormal
    Findcontractor_Thread.Start()
End Sub


Delegate Sub FindContractorDelegate(ByVal igGrid As Infragistics.Windows.DataPresenter.XamDataGrid, ByVal webbrowser As Controls.WebBrowser)


Private Sub FindContractor_ThreadExecute()
    Dim threadControls(1) As Object
    threadControls(0) = Me.XamDataGrid1
    threadControls(1) = Me.WebBrowserMap

    Dim m As FindContractorDelegate = AddressOf FindContractor_WorkingThread
    Me.Dispatcher.BeginInvoke(m, threadControls)
End Sub


Private Sub FindContractor_WorkingThread()

    Mouse.OverrideCursor = Cursors.Wait

'Do something...

    Mouse.OverrideCursor = Nothing
End Sub

我做错了什么?

谢谢, 尼尔斯

4 个答案:

答案 0 :(得分:4)

您可以使用“'做某事'中的winforms控件。控件只能在UI线程中进行主要设置。

因此,“BeginInvoke”在UI线程中调用目标。所以你创建了te paralel线程,但整个想法再次在UI线程中进行。

答案 1 :(得分:2)

使用Dispatcher.CurrentDispatcher.BeginInvoke解决此问题。

出现此问题的原因是Dispatcher实例在GUI线程上调用,但Dispatcher.CurrentDispatcher将为当前正在执行的线程创建一个新的Dispatcher实例(如果不存在)。

这在概念上类似于Windows如何为创建自己创建winform的新线程创建消息队列。

答案 2 :(得分:1)

Dim Findcontractor_Thread As New Thread(AddressOf FindContractor_ThreadExecute)
Findcontractor_Thread.Priority = ThreadPriority.AboveNormal
Findcontractor_Thread.Start()

用于带参数的线程调用

trd_copy.ParameterizedStart(src)

Delegate Sub nameofDelegate(s As Integer)
Sub nameofDelegate+NameofSub(ByVal s As Integer)
If Form1.ProgressBar1.InvokeRequired Then
    Dim d As New nameofDelegate (AddressOf nameofDelegate+NameofSub)
    NameOfYourForm.Invoke(d, New Object() {s})
Else
    If s = 1 Then
        NameOfYourForm.ProgressBar1.Refresh() ** Or other Gui Functions
    Else

    End If
End If

End Sub

对于没有参数的线程调用

trd_copy.Start()

Delegate Sub nameofDelegate()
Sub nameofDelegate+NameofSub()
If Form1.ProgressBar1.InvokeRequired Then
    Dim d As New nameofDelegate (AddressOf nameofDelegate+NameofSub)
    NameOfYourForm.Invoke(d, New Object())
Else
   NameOfYourForm.ProgressBar1.Refresh() ** Or other Gui Functions
End If
End Sub

请记住,当您第一次启动一个线程并且您在模型中进行编码时,您必须将(我)传递给初始线程,因为VB具有“默认表单实例”的概念。对于应用程序命名空间中的每个Form,将在Forms属性下的My命名空间中创建一个默认实例。

,这只是添加一个额外的参数,如此

Private Sub FindCustomerLocation()
Dim Findcontractor_Thread As New Thread(AddressOf FindContractor_ThreadExecute)
Findcontractor_Thread.Priority = ThreadPriority.AboveNormal
Findcontractor_Thread.Start(me)
End Sub



Private Sub FindContractor_ThreadExecute(beginform as *NameOfFormComingFrom*)
Dim threadControls(1) As Object
threadControls(0) = Me.XamDataGrid1
threadControls(1) = Me.WebBrowserMap


FindContractor_WorkingThread(threadControls,beginform)
End Sub


Delegate Sub FindContractor_WorkingThread(s As Integer,beginform as   *NameOfFormComingFrom*)
Sub FindContractor_WorkingThreadInvoke(ByVal s As Integer,beginform as *NameOfFormComingFrom*)
If beginform.mouse.InvokeRequired Then
    Dim d As New FindContractor_WorkingThread(AddressOf    FindContractor_WorkingThreadInvoke)
    beginform.Invoke(d, New Object() {s,beginform})
Else
     beginform.Mouse.OverrideCursor = Cursors.Wait

    'Do something...

    beginform.Mouse.OverrideCursor = Nothing
End If
End Sub

答案 3 :(得分:-2)

您的新主题具有更高的优先级,因此会导致UI冻结它所做的任何事情(只要它是部分密集的)