none
BackGroundWorker ne s'arrête pas... RRS feed

  • Question

  • Bonjour,

     

    J'ai un problème avec mon backgroundworker, l'annulation ne provoque pas l'évènement RunWorkerComplete.

    Voici mon code :

     

    public TCamera()
            {
                BackGroundWorkerAcquisitionVideo = new System.ComponentModel.BackgroundWorker();
                BackGroundWorkerAcquisitionVideo.WorkerSupportsCancellation = true;
                BackGroundWorkerAcquisitionVideo.DoWork += new DoWorkEventHandler(BackGroundWorkerAcquisitionVideo_DoWork);
                BackGroundWorkerAcquisitionVideo.RunWorkerCompleted += 
    new RunWorkerCompletedEventHandler(BackGroundWorkerAcquisitionVideo_RunWorkerCompleted); } ~TCamera() { //Fermeture de caméra si elle était ouverte ou attrapée if (LaCam != null) { try { if (Pylon.DeviceIsOpen(LaCam)) { if(BackGroundWorkerAcquisitionVideo.IsBusy) { StopStream(); } Pylon.DeviceClose(LaCam); } Pylon.DestroyDevice(LaCam); } catch { } } Pylon.Terminate(); } public void StartStream() { BackGroundWorkerAcquisitionVideo.RunWorkerAsync(); } public void StopStream() { BackGroundWorkerAcquisitionVideo.CancelAsync(); while (BackGroundWorkerAcquisitionVideo.IsBusy) ; } private void BackGroundWorkerAcquisitionVideo_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker ThreadAcquisition = sender as BackgroundWorker; [...] do { //Si on a demandé l'arrêt de la capture if (ThreadAcquisition.CancellationPending == true) { e.Cancel = true; break; } else { [...]<br/>  } } while (true); } private void BackGroundWorkerAcquisitionVideo_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { [...] } }

     


    Visiblement j'ai un problème avec l'attente de la fin du thread (c'en est bien un ?). Si je la met (que ce soit IsBusy ou une variable maison), le programme passe bien par e.Cancel = true, mais n'exécute jamais ce que j'ai dans RunWorkerComplete(). Si j'enlève l'attente, tout se passe normalement.

    Comment puis-je être certain que tout s'est arrêté avant de faire autre chose ?


    • Modifié Robix66 lundi 2 janvier 2012 12:41
    lundi 2 janvier 2012 12:41

Réponses

  • Bonjour,

     

    Malheureusement le programme ne rentre toujours pas dans RunWorkerCompleted dans ce cas là, le signal n'est donc jamais envoyé.

    (Pour lancer le signal c'est plutôt waitEvent.Set(), non ? Enfin, ça ne fonctionne toujours pas vu que le programme ne passe pas ici).

     

    Edit :

    A priori, c'est bon en utilisant :

     

        // Wait for the BackgroundWorker to finish the download.
        while (this.backgroundWorker1.IsBusy)
        {
            // Keep UI messages moving, so the form remains 
            // responsive during the asynchronous operation.
            Application.DoEvents();
        }

     

    Trouvé ici : http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.isbusy%28v=vs.80%29.aspx

    J'ai pourtant plusieurs fois retrouvé votre solution, étrange qu'elle ne veuille pas fonctionner ici...

     

    Merci de votre aide.

    • Modifié Robix66 lundi 2 janvier 2012 14:29
    • Marqué comme réponse Robix66 lundi 2 janvier 2012 14:30
    lundi 2 janvier 2012 13:36

Toutes les réponses

  • Bonjour,

    Si vous voulez attendre le BackgroundWorker, il faut utiliser un mécanisme de notification (signal) par exemple en utilisant AutoResetEvent :

    private AutoResetEvent waitEvent = new AutoResetEvent(false); 
     
    public void StopStream()
    {
         BackGroundWorkerAcquisitionVideo.CancelAsync();
         waitEvent.WaitOne(); // Attendre le signal
     }
     
    private void BackGroundWorkerAcquisitionVideo_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
          [...]
          // Signaler la fin du traitement
          waitEvent.WaitOne(); 
    }
    
    

    Est-ce que cela répond à votre problème ?

    Cordialement


    Gilles TOURREAU - MVP C#
    Architecte .NET/Consultant/Formateur chez Winwise
    Blog : http://gilles.tourreau.fr
    - MCPD : Enterprise Developper / Windows Developper 3.5 / ASP .NET 3.5
    - MCITP : SQL Server 2008 Developper
    - MCTS : ADO .NET 3.5 / SQL Server 2008 Developper / Windows Forms 3.5 / ASP .NET 3.5
    lundi 2 janvier 2012 13:17
    Modérateur
  • Bonjour,

     

    Malheureusement le programme ne rentre toujours pas dans RunWorkerCompleted dans ce cas là, le signal n'est donc jamais envoyé.

    (Pour lancer le signal c'est plutôt waitEvent.Set(), non ? Enfin, ça ne fonctionne toujours pas vu que le programme ne passe pas ici).

     

    Edit :

    A priori, c'est bon en utilisant :

     

        // Wait for the BackgroundWorker to finish the download.
        while (this.backgroundWorker1.IsBusy)
        {
            // Keep UI messages moving, so the form remains 
            // responsive during the asynchronous operation.
            Application.DoEvents();
        }

     

    Trouvé ici : http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.isbusy%28v=vs.80%29.aspx

    J'ai pourtant plusieurs fois retrouvé votre solution, étrange qu'elle ne veuille pas fonctionner ici...

     

    Merci de votre aide.

    • Modifié Robix66 lundi 2 janvier 2012 14:29
    • Marqué comme réponse Robix66 lundi 2 janvier 2012 14:30
    lundi 2 janvier 2012 13:36
  • Bonjour,

     

    Merci pour avoir partagé avec nous la solution.

     

    Bonne journée,

     

    Cipri


    Suivez MSDN sur Twitter   Suivez MSDN sur Facebook


    Ciprian DUDUIALA, MSFT  
    •Nous vous prions de considérer que dans le cadre de ce forum on n’offre pas de support technique et aucune garantie de la part de Microsoft ne peut être offerte.

    mercredi 11 janvier 2012 10:41