2016-11-15 1 views
0

J'utilise un thread de travail pour charger des images .png (d'une chaîne de chemin) dans un objet PictureBox2 global, puis quitte le _RunWorkerCompleted pour utiliser la largeur et la hauteur de PictureBox2 pour un travail supplémentaire dans la méthode appelée processpic2 . Tout fonctionne bien jusqu'à ce que la cinquième ou la sixième image ait été ajoutée au PB. A ce stade, dans la méthode processpic2, une exception est levée car la propriété image de PictureBox2 est nulle.PictureBox cesse d'ajouter des images

Pourquoi un PB arrêterait-il de prendre des photos après un certain temps?

Public Class Form1 
Public WithEvents BackgroundWorker1 As New System.ComponentModel.BackgroundWorker 

Private Sub BackGroundworker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork 
    Dim args As ArgumentType = e.Argument 
    PictureBox2.Image = Nothing 
    PictureBox2.Invalidate() 
    Dim img As Image 
    Using str As Stream = File.OpenRead(args._pathstr) 
     img = Image.FromStream(str) 
    End Using 
    PictureBox2.Image = img 
    e.Result = "done" 
End Sub 

Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) _Handles BackgroundWorker1.RunWorkerCompleted 
    'Called when the BackgroundWorker is completed. 
    processpic2() 
End Sub 

Sub btnLoadPicture(pathstr) 
    Dim args As ArgumentType = New ArgumentType() 
    args._pathstr = pathstr 
    BackgroundWorker1.RunWorkerAsync(args) 
End Sub 

Sub processpic2() 
    If PictureBox2.Image Is Nothing Then MsgBox("Image is Nothing") 
End Sub 
+1

Ne pas traite les éléments de l'interface utilisateur du travailleur de fond, c'est pourquoi ... Utilisez un délégué et invoquez ... La zone d'image est sur un fil différent de celui de l'arrière-plan ... – Codexer

+0

Je ne pense pas avoir besoin de répondre à cette question, donc pourquoi le commentaire. Rechercher invoke pour le contrôle de l'interface utilisateur avec lequel vous travaillez qui vous mènera dans la bonne direction. Si vous avez encore besoin d'aide, veuillez mettre à jour votre question et nous serons heureux de vous aider. – Codexer

+1

Je suis d'accord avec Zaggler. Vous pouvez éventuellement renvoyer l'image chargée dans RunWorkerCompletedEventArgs (c.-à-d. 'E.Result') et définir' PictureBox.Image' dans RunWorkerCompleted. – SSS

Répondre

1

Le point entier d'un BackgroundWorker est de faire un travail d'arrière-plan. Apporter des modifications à l'interface utilisateur est exactement le contraire du travail de fond. C'est un travail d'avant-plan. Si votre tâche consiste à effacer le contenu actuel d'un PictureBox, charger une image à partir d'un fichier, puis afficher cette image, seule l'étape intermédiaire est le travail en arrière-plan, seule l'étape intermédiaire doit être effectuée dans le gestionnaire d'événements DoWork. La première étape doit être effectuée avant d'appeler le RunWorkerAsync et la dernière étape doit être effectuée dans le gestionnaire d'événements RunWorkerCompleted.

Après tout cela, pourquoi utiliser un BackgroundWorker dans ce cas? Pourquoi ne pas simplement appeler la méthode LoadAsync du PictureBox lui-même?

+0

Merci - n'était pas au courant d'une méthode 'LoadAsync' pour un' PictureBox' donc va se pencher sur cela. Une chose est sûre, les images font environ 600 x 400 pixels .png et même lors de la définition de 'PictureBox1.Image = Nothing', la zone d'image a tendance à se bloquer après le chargement et l'affichage de 5-8 images. Il semble que certains contenus de la mémoire se remplissent ou quelque chose. 'PictureBox1.Invalidate' et' PictureBox1.Image = Nothing' ne contribuent pas à éradiquer cette particularité. – wrtsvkrfm

+0

Une 'Image' est un objet jetable. Si vous créez un objet 'Image' et que vous l'attribuez à la propriété' Image' d'un objet 'PictureBox', vous devriez appeler' Dispose' sur cet objet 'Image' quand vous en avez fini avec. – jmcilhinney

0

SOLUTION - grâce aux suggestions reçues, et ce que je trouve sur MSDN concernant la méthode LoadAsync de PictureBox le code suivant a résolu le problème:

PictureBox2.Image = Nothing 

PictureBox2.WaitOnLoad = False 

' Load the image asynchronously. 
PictureBox2.LoadAsync(pathstr)