当单击一个按钮时,我启动一个单独的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
我做错了什么?
谢谢, 尼尔斯
答案 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冻结它所做的任何事情(只要它是部分密集的)