Avant de commencer, je sais que vous avez déjà un tas de réponses à cette question, mais laissez-moi vous expliquer ce qui se passe. Je veux fondamentalement ajouter des textes à un élément RichTextBox, cela me sert comme un logger pour informer l'utilisateur de chaque action d'un traitement de fichier, mais le texte est ajouté à la RichTextBox via une boucle for, et si j'exécute cette boucle dans la même classe "Form1.vb" l'interface utilisateur gèle jusqu'à la fin de la boucle.Comment définir le texte à l'élément créé dans un autre thread
J'ai décidé d'exécuter la boucle dans un thread séparé pour éviter le gel de l'interface utilisateur, et c'est là que mon problème commence.
Form1.vb
Imports System.Threading
Public Class Form1
Dim myThread As Thread
Private Sub appendMyText()
' Cross-thread operation not valid: Control txtLogger accessed from a thread other than the thread it was created on.
txtLogger.AppendText("Hello World" & vbNewLine)
End Sub
Private Sub btnTest_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnTest.Click
myThread = New Thread(New ThreadStart(AddressOf appendMyText))
myThread.Start()
End Sub
End Class
Je ne peux pas accéder à l'élément txtLogger d'un autre fil, alors j'ai essayé l'exemple MSDN https://msdn.microsoft.com/en-us/library/ms171728(v=vs.110).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-2
Il me montre comment accéder à l'élément effectuer des appels à thread sécurisé, en utilisant un délégué.
donc mon code est édité
Form1.vb
Imports System.Threading
Public Class Form1
Dim myThread As Thread
Delegate Sub AppendMyText(ByVal text As String)
' Add the text to RichTextBox
Private Sub addText(ByVal txt As String)
If txtLogger.InvokeRequired Then
Dim myDelegate = New AppendMyText(AddressOf addText)
Me.Invoke(myDelegate, {txt})
Else
txtLogger.AppendText(txt)
End If
End Sub
' Call the method that add text to RichTextBox
Private Sub threadSafe()
Me.addText("Hello World" & vbNewLine)
End Sub
Private Sub btnTest_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnTest.Click
myThread = New Thread(New ThreadStart(AddressOf threadSafe))
myThread.Start()
End Sub
End Class
Le code fonctionne vraiment cette façon, le texte est joint en annexe à RichTextBox, mais le tout le code est dans la même classe Form1.vb
Dans mon projet d'origine, la boucle for est exécutée dans une autre classe, je vais la nommer "Class1.vb" ici.
C'est l'exemple de code
Class1.vb
Public Class Class1
Public Sub count()
Dim i As Integer
For i = 0 To 100
' this method will be executed by thread "myThread"
' how to append text to txtLogger from here?
Debug.WriteLine("Index: {0}", i)
Next
End Sub
End Class
Vous pouvez transmettre la forme en tant que paramètre à la méthode 'count'. –
J'ai déjà essayé de cette façon. Mais accéder directement aux éléments d'un autre thread n'est pas recommandé, et je sais pourquoi! Mon projet doit ajouter du texte plus de 200 fois, et l'application s'arrête de répondre et se bloque lorsque je passe le formulaire en paramètre, car le formulaire s'exécute sur son propre thread. –
L'accès à une méthode personnalisée via le formulaire doit toujours être possible tant que cette méthode appelle l'accès aux éléments de l'interface utilisateur. –