Новый поток все еще блокирует UI-поток - PullRequest
1 голос
/ 17 июля 2009

при нажатии кнопки я запускаю отдельную команду, которая заполняет сетку и что-то делает с веб-браузером-контролем. Но когда кнопка нажата, новый поток, кажется, не является отдельным, потому что пользовательский интерфейс зависает, пока новый поток не будет завершен.

Вот код:

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 ]

4 голосов
/ 17 июля 2009

Вы, вероятно, работаете с элементами управления winforms в разделе "сделай что-нибудь". Элементы управления могут быть активированы только в потоке пользовательского интерфейса.

Итак, «BeginInvoke» вызывает цель в этом потоке пользовательского интерфейса. Таким образом, вы создаете параллельную ветку, но все мысли снова возникают в пользовательском интерфейсе.

2 голосов
/ 17 июля 2009

Используйте Dispatcher.CurrentDispatcher.BeginInvoke для решения этой проблемы.

Проблема возникает из-за того, что экземпляр Dispatcher вызывается в потоке GUI, но Dispatcher.CurrentDispatcher создаст новый экземпляр Dispatcher для текущего исполняющего потока, если он не существует.

В принципе это похоже на то, как Windows будет создавать очереди сообщений для новых потоков, которые сами создают winform.

1 голос
/ 27 июня 2013
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 есть понятие "экземпляры форм по умолчанию". Для каждой формы в пространстве имен приложения будет создан экземпляр по умолчанию, созданный в пространстве имен My в свойстве Forms.

и это просто добавление дополнительного параметра, например, так:

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
0 голосов
/ 17 июля 2009

Ваш новый поток имеет более высокий приоритет, поэтому пользовательский интерфейс будет зависать независимо от того, что он делает (если он частично интенсивный)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...