when a button is clicked i start a seperate thead which is population a grid and does something with a webbrowser-control. But when the button is click the new thread seems not to be seperate, cause the UI is freezing until the new thread is done.
当单击一个按钮时,我启动一个单独的thead,它是一个网格,并使用webbrowser-control做一些事情。但是当单击该按钮时,新线程似乎不是单独的,导致UI冻结,直到新线程完成。
Here the code:
这里的代码:
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
What I'm doing wrong?
我做错了什么?
Thanks, Neils
4 个解决方案
#1
You propabldy working with the winforms controls in the "'do something". The controls can be mainupulated only in UI thread.
您可以在“'做某事'中使用winforms控件。控件只能在UI线程中进行主要设置。
So, the "BeginInvoke" call the target in ths UI thread. So you create te paralel thread, but the whole think is doing in UI thread again.
因此,“BeginInvoke”在UI线程中调用目标。所以你创建te paralel线程,但整个想法再次在UI线程中。
#2
Use Dispatcher.CurrentDispatcher.BeginInvoke
to solve this problem.
使用Dispatcher.CurrentDispatcher.BeginInvoke来解决此问题。
The issue occurs because the Dispatcher
instance invokes on the GUI thread but Dispatcher.CurrentDispatcher
will create a new Dispatcher
instance for the current executing thread if one does not exist.
出现此问题的原因是Dispatcher实例在GUI线程上调用,但Dispatcher.CurrentDispatcher将为当前正在执行的线程创建一个新的Dispatcher实例(如果不存在)。
This is similar in concept to how Windows will create message queues for new threads that are created that themselves create a winform.
这与Windows将如何为创建自己创建winform的新线程创建消息队列的概念类似。
#3
Dim Findcontractor_Thread As New Thread(AddressOf FindContractor_ThreadExecute)
Findcontractor_Thread.Priority = ThreadPriority.AboveNormal
Findcontractor_Thread.Start()
for threads calls with parameters
用于带参数的线程调用
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
For Thread calls without parametrs
对于没有参数的线程调用
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
Keep in mind when you first Start a Thread and you are coding in a Model you MUST pass (me) into the initial thread because of VB having a concept of "Default Form Instances". For every Form in the application's namespace, there will be a default instance created in the My namespace under the Forms property.
请记住,当您第一次启动一个线程并且您正在编写模型时,您必须将(我)传递给初始线程,因为VB具有“默认表单实例”的概念。对于应用程序命名空间中的每个Form,将在Forms属性下的My命名空间中创建一个默认实例。
and that is just adding an additional parameter like so
这只是添加一个额外的参数
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
#4
Your new thread has a higher priority, so will cause the UI to freeze whatever it does (as long as it is partly intensive)
您的新线程具有更高的优先级,因此将导致UI冻结它所做的任何事情(只要它是部分密集的)
#1
You propabldy working with the winforms controls in the "'do something". The controls can be mainupulated only in UI thread.
您可以在“'做某事'中使用winforms控件。控件只能在UI线程中进行主要设置。
So, the "BeginInvoke" call the target in ths UI thread. So you create te paralel thread, but the whole think is doing in UI thread again.
因此,“BeginInvoke”在UI线程中调用目标。所以你创建te paralel线程,但整个想法再次在UI线程中。
#2
Use Dispatcher.CurrentDispatcher.BeginInvoke
to solve this problem.
使用Dispatcher.CurrentDispatcher.BeginInvoke来解决此问题。
The issue occurs because the Dispatcher
instance invokes on the GUI thread but Dispatcher.CurrentDispatcher
will create a new Dispatcher
instance for the current executing thread if one does not exist.
出现此问题的原因是Dispatcher实例在GUI线程上调用,但Dispatcher.CurrentDispatcher将为当前正在执行的线程创建一个新的Dispatcher实例(如果不存在)。
This is similar in concept to how Windows will create message queues for new threads that are created that themselves create a winform.
这与Windows将如何为创建自己创建winform的新线程创建消息队列的概念类似。
#3
Dim Findcontractor_Thread As New Thread(AddressOf FindContractor_ThreadExecute)
Findcontractor_Thread.Priority = ThreadPriority.AboveNormal
Findcontractor_Thread.Start()
for threads calls with parameters
用于带参数的线程调用
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
For Thread calls without parametrs
对于没有参数的线程调用
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
Keep in mind when you first Start a Thread and you are coding in a Model you MUST pass (me) into the initial thread because of VB having a concept of "Default Form Instances". For every Form in the application's namespace, there will be a default instance created in the My namespace under the Forms property.
请记住,当您第一次启动一个线程并且您正在编写模型时,您必须将(我)传递给初始线程,因为VB具有“默认表单实例”的概念。对于应用程序命名空间中的每个Form,将在Forms属性下的My命名空间中创建一个默认实例。
and that is just adding an additional parameter like so
这只是添加一个额外的参数
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
#4
Your new thread has a higher priority, so will cause the UI to freeze whatever it does (as long as it is partly intensive)
您的新线程具有更高的优先级,因此将导致UI冻结它所做的任何事情(只要它是部分密集的)