2017-10-15 4 views
0

J'ai donc passé toute la fin de semaine à lire et à faire des recherches sur Multithreading dans .net et il y a une question que je n'arrive pas à comprendre. Disons que j'ai un bouton et quand je clique sur ce bouton je veux télécharger un fichier sur Amazon S3, maintenant évidemment cette tâche de téléchargement prendra quelques secondes et je ne veux pas arrêter tout le reste pendant ce temps. Donc, c'est là que le fil entre.multithread scope

Alors, un problème survient, si l'utilisateur clique à nouveau sur le bouton, je ne veux pas démarrer un autre thread pour télécharger le fichier, sauf si le premier thread est complètement terminé, pour essayer pour éviter la redondance.

partout où je lis concernant multithreading décrit décrire le fil quand je l'ai exigé, mais si je fais cela sur un bouton cliquez sûrement je vais créer une sorte de conflit avec le nom du fil comme la deuxième fois le bouton est cliqué il y aura déjà un fil avec le même nom. Donc, ma solution était de déclarer le thread au début de la classe. Créer un sous avec le code pour télécharger le fichier. puis, lorsque vous cliquez sur le bouton, vérifiez si le thread est actif avant de l'exécuter. mais ensuite j'ai découvert que je ne peux pas faire un fil recommencer une fois qu'il a fini.

Donc ce que je n'arrive pas à comprendre, c'est comment je parviens à faire exécuter une tâche qui doit être exécutée plusieurs fois dans un thread séparé. Suis-je censé créer un nouveau fil chaque fois que je le veux? Est-ce que cela signifie que je vais devoir créer un nouveau thread avec un nom unique? Qu'arrive-t-il à un fil une fois qu'il est terminé? J'ai lu qu'abandonner un fil est très mauvais, mais suis-je censé le laisser là pour toujours ne pas faire rien et incapable de l'enlever? cela signifie-t-il que si l'application fonctionne pendant une longue période de temps, je pourrais me retrouver avec des milliers de threads "morts" qui ne font rien?

Voici une version de balisage de ce que je fais au cas où cela faciliterait les choses pour les gens.

Public Class Form1 
    Shared UploadThread As Thread = New Thread(AddressOf UploadLoop) 

    Shared Sub UploadLoop() 
     'code to upload a file to amazon S3 
    End Sub 

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
     If (UploadThread.IsAlive) Then 
      MsgBox("upload not completed") 
     Else 
      UploadThread.Start() 
     End If 
    End Sub 
End Class 
+3

Il suffit de définir la propriété Enabled du bouton sur * False *. Activez-le à nouveau lorsque le transfert est terminé, vous préférerez l'événement RunWorkerCompleted fourni par BackgroundWorker. Peasy facile. –

Répondre

0

Un thread terminé est dans un état "mort". Vous ne pouvez pas facilement faire grand chose avec cela et vous devriez plutôt instancier un nouveau thread à chaque fois:

Shared UploadThread As Thread 

Private Sub Button1_Click(sender As Object, e As EventArgs) 
    If UploadThread IsNot Nothing AndAlso UploadThread.IsAlive Then 
     MsgBox("upload not completed") 
    Else 
     UploadThread = New Thread(New ThreadStart(AddressOf UploadLoop)) 
     UploadThread.Start() 
    End If 
End Sub 
+0

merci bob, donc je peux continuer à utiliser le même nom pour le fil que je viens de le déclarer à nouveau? –

+0

Egalement, que se passe-t-il si cela se fait 1000 fois, il y aura 999 morts dans la mémoire ou seront-ils nettoyés chaque fois que le fil est redéfini? –

+0

@SimonGreen: Le "nom" est le nom de la variable pointant vers votre discussion. Le thread réel n'a pas de nom et sortira de la portée si vous définissez la variable sur une nouvelle instance de thread - ce qui nous amène à votre deuxième question: Lorsqu'un objet géré sort de sa portée, il sera détecté par le garbage collector (quand il s'exécute) comme n'ayant plus de références à celui-ci. Le Garbage Collector récupère alors l'objet, libérant ainsi toute la mémoire qu'il a réservée. Donc ** non **: Vous ** n'aura pas 999 fils morts, un seul fil actif. –