2017-02-23 1 views
0

J'utilise C#, Net4.0 et Visual Studio 2010 et j'essaie d'obtenir ce comportement de mon application de formulaire Windows lorsque l'utilisateur clique sur un bouton:C# Démarrer et arrêter le fil dans le bouton SAME cliquez sur l'événement

  1. Une interface graphique LED clignote
  2. une opération longue échelon commence
  3. Lorsque l'opération se termine au point 2 de la LED cesse de clignoter

    private void Btn_WebService_Click(object sender, EventArgs e) 
    { 
        Thread_Blink = new Thread(() => { LED_Blink(LED.WS); }); 
        Thread_Blink.Start(); 
    
        // Do something that takes time.. Let's imulate with a sleep 
        Thread.Sleep(2000); 
    
        Thread_Blink.Abort(); 
    } 
    

J'ai aussi essayé d'utiliser 3 différents événements et/ou des minuteries ..

private void Btn_WebService_MouseDown(object sender, MouseEventArgs e) 
{ 
    Timer_Blink.Enabled = true; 
} 

private void Btn_WebService_Click(object sender, EventArgs e) 
{ 
    // Do something that takes time.. Let's imulate with a sleep 
    Thread.Sleep(2000); 
} 

private void Btn_WebService_MouseUp(object sender, MouseEventArgs e) 
{ 
    Timer_Blink.Enabled = false; 
} 

Le résultat est toujours le même: La LED commence à clignoter seulement à la fin de la longue opération de fonctionnement (Thread.Sleep(2000);) et ARRÊTS soudainement de sorte que vous ne puissiez rien voir. Pourquoi cela arrive-t-il et comment puis-je obtenir le comportement souhaité?

J'ajoute plus d'infos. J'ai essayé d'utiliser BackgroundWorked et mis à exécution les behavour voulu ainsi:

private void Btn_WebService_Click(object sender, EventArgs e) 
    { 
     BlinkWorker.RunWorkerAsync(LED.WS); 
     LedOn(LED.WS); 

     TestWebService(); // This method takes about 2 seconds to answer.. 

     LedOff(LED.WS); 
     BlinkWorker.CancelAsync(); 
    } 

Alors que le TestWebService() est en cours d'exécution, je reçois la LED éteinte (LEDOn (LED.WS);). Lorsque TestWebService() a terminé, le voyant s'allume. Le BlinkWorker ne fonctionne toujours pas s'il est démarré et annulé dans l'événement Click.

FYI: Si je fais un bouton qui commence à clignoter et un autre bouton qui l'arrête, cela fonctionne parfaitement.

Répondre

0

Je vous propose de regarder la classe BackgroundWorker et la méthode ReportProgress.

1

Le problème est que vous tirez le fil de l'interface utilisateur à l'intérieur de Thread.Sleep. Le thread d'interface utilisateur est spécial - il est le seul qui peut apporter des modifications à l'interface utilisateur - alors qu'il est occupé à dormir, il n'est pas en mesure de gérer les tentatives de rappel BackgroundWorker ou LED_Blink pour modifier l'état de l'interface utilisateur. Par conséquent, vous n'avez pas besoin d'attacher le thread de l'interface utilisateur. Vous devez placer le code Thread.Sleep (ou son équivalent réel réel) dans le gestionnaire BackgroundWorkerDoWork, ou utiliser d'autres moyens pour éviter de bloquer le fil d'interface utilisateur.

approches communes aujourd'hui seraient d'utiliser async/await si le travail réel que vous essayez de faire offre déjà une alternative asynchrone (par exemple await Task.Delay(2000); serait l'équivalent de votre Thread.Sleep(2000); actuelle). Malheureusement, en utilisant async et await vous auriez besoin de passer à une version ultérieure de .NET/Visual Studio - mais vous devriez en tenir compte de toute façon. 2010 est assez daté (et aussi, IMO, probablement le pire à arrêter - c'était notoirement lent), et .NET 4.0 (par opposition à .NET 4.5.2 ou plus tard) n'est plus supporté.