2009-07-17 12 views
1

quand un bouton est cliqué je démarre un thead séparé qui est une grille de population et fait quelque chose avec un webbrowser-contrôle. Mais lorsque le bouton est cliqué, le nouveau thread ne semble pas être séparé, car l'interface utilisateur gèle jusqu'à ce que le nouveau thread soit terminé.Le nouveau thread bloque toujours l'UI-Thread

Voici le 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 

Ce que je fais mal?

Merci, Neils

Répondre

4

Vous propabldy travailler avec les contrôles WinForms dans le «faire quelque chose». Les contrôles peuvent être maintenus uniquement dans le thread UI. Ainsi, le "BeginInvoke" appelle la cible dans le thread d'interface utilisateur. Donc, vous créez le thread Parallel, mais l'ensemble pense faire dans le fil de l'interface utilisateur à nouveau.

+0

Dans mon thread séparé, je travaillais avec WinForms et le système fait jeter une exception de rapporter ce que vous dites. – Zac

-2

Votre nouveau thread a une priorité plus élevée, donc provoquera l'interface utilisateur de geler ce qu'il fait (aussi longtemps qu'il est en partie intensive)

2

Utilisez Dispatcher.CurrentDispatcher.BeginInvoke pour résoudre ce problème.

Le problème se produit car l'instance Dispatcher invoque sur le thread graphique, mais Dispatcher.CurrentDispatcher va créer une nouvelle instance Dispatcher pour le thread en cours d'exécution si elle n'existe pas.

Ce concept est similaire à la façon dont Windows va créer des files d'attente de messages pour les nouveaux threads qui créent eux-mêmes un winform.

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

pour les fils téléphoniques avec des paramètres

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

Pour les appels de discussion sans 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 

Gardez à l'esprit lorsque vous démarrez un fil et vous êtes codage dans un modèle, vous devez passer (moi) dans le fil initial en raison de VB avoir un concept de "Instances de formulaire par défaut". Pour chaque formulaire dans l'espace de noms de l'application, il y aura une instance par défaut créée dans l'espace de noms Mon sous la propriété Formulaires.

et qui est tout simplement l'ajout d'un paramètre supplémentaire comme si

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 
Questions connexes