2010-09-25 8 views
0

J'utilise Visual C# .Net via Visual Studio 2008 Express et je lance un thread à partir d'une application de formulaires pour attendre les données entrantes en boucle. Ainsi, chaque boucle attend que les données soient disponibles, puis obtient les données et recommence à attendre.Visual C#, Thread enfant arrête le traitement sur le thread parent. Pourquoi?

La principale raison pour laquelle j'attends mes données dans un thread séparé est que mon formulaire permet toujours l'interaction pendant que l'autre reste là en attente de données.

Pour une raison quelconque, mon formulaire se verrouille pendant que mon autre thread est en attente.

Malheureusement, je suis obligé d'utiliser une fonction propriétaire pour acquérir mes données. Le traitement s'arrêtera littéralement à cette fonction jusqu'à ce que les données lui soient renvoyées (ce qui attend les entrées matérielles). Ainsi, un utilisateur peut cliquer en vain sur les options de menu sans effet, jusqu'à ce que le thread fils renvoie des données et que toutes les options de menu cliquées changent rapidement d'état et se verrouillent à nouveau. Donc, ma question est:
Pourquoi mon fils enfile-t-il ma forme? Is not est supposé être indépendant? Que puis-je faire pour forcer mon formulaire à continuer à fonctionner si ce thread enfant attend quelque chose?

Je fais actuellement mon fils comme ceci:

ControlThread = new Thread(new ThreadStart(Run)); 
ControlThread.Start(); 

Lorsque ma fonction Run est quelque chose comme ceci:

public void Run() 
{ 
    while (!StopEventHandle.WaitOne(0, true)) 
    { 
     int data = WaitForData(); 
     invoke(DelegatedResults); 
    } 
} 

Où DelegatedResults est une fonction sur ma forme qui met à jour des zones de texte en utilisant la données qui sont entrées.

+1

Vous pouvez essayer d'utiliser la classe BackgroundWorker à la place pour éviter une gestion de thread plus complexe. –

+0

La classe BackgroundWorker, tout en semblant beaucoup plus simple que ce que j'avais fait pour gérer mes threads, ne permettra toujours pas à mon thread principal de continuer si mon thread fils est en attente. –

Répondre

1

Je suis obligé d'utiliser une fonction exclusive d'acquérir mes données

Vous ne parlait pas beaucoup à propos de cette fonction. Votre problème suggère qu'il a été implémenté en tant que serveur COM, assez commun. COM prend en charge les exigences de thread pour le serveur COM. Un tel serveur indique dans le registre avec la clé de registre ThreadingModel quel genre de threads il supporte. Un très le paramètre commun est "Appartement", également par défaut lorsque la clé est manquante.

Ce paramètre indique que le serveur ne prend pas en charge le thread. Il a besoin d'un appartement à fil unique (STA). COM prend soin de cela et il marshals automatiquement tout appel effectué sur le serveur à un thread STA. Votre fil d'interface utilisateur. Ce qui devient ainsi mort comme un doornail jusqu'à ce que l'appel se termine.

Il devrait y avoir quelque chose à ce sujet dans la documentation de la bibliothèque. Contacter le fournisseur pour obtenir de l'aide serait également une bonne idée. Si vous ne pouvez pas obtenir d'aide, la première chose à faire est d'initialiser le serveur sur le thread de travail à la place de votre thread d'interface utilisateur. Cela résoudrait le problème si le ThreadModel est "Both". Si cela ne vous aide pas, vous devrez créer votre propre thread STA. Appelez le fil.SetApartmentState() avant de démarrer le thread, démarrez votre propre boucle de messages avec Application.Run() dans le thread. Vous pourriez être en mesure de sauter la boucle, mais il est normalement nécessaire.

+0

Il est très probable que la fonction que j'utilise pour saisir mes données soit configurée pour fonctionner de la manière la plus incommode possible, la documentation est très limitée et provient d'un autre continent. Cela dit, je vais probablement devoir m'en remettre à la suggestion de discussion STA. Je suis très novice en matière de threading. Que voulez-vous dire par "commencer votre propre boucle de message"? –

+1

Lien: http://stackoverflow.com/questions/1995527/how-might-i-create-and-use-a-webbrowser-control-on-a-worker-thread/1995667#1995667 –

+0

Un peu d'information supplémentaire à partir de la fonction que j'utilise: Elle provient d'une bibliothèque dotNet, mais elle accède à d'autres bibliothèques qui peuvent avoir ou non des composants COM. Ce que cette fonction fait est d'attendre un tampon à remplir, puis saisir les données du tampon, puis dire au tampon de recommencer à remplir. Si le tampon n'est pas plein lorsque la fonction est appelée, il attend. Il n'y a aucun moyen de vérifier l'état du tampon. –

0

Vous devriez dormir ce fil au moins par 1.

RÉPONSE À COURT ::

this.Invoke((ThreadStart)delegate() 
{ 
    textBox1.Text = "Yahoo"; 
}); 

:: Réponse longue

using System.Threading; 

namespace WindowsFormsApplication1 
{ 
    public partial class Form1 : Form 
    { 
     Thread thread; 
     bool finishingThread, finished; 

     public Form1() 
     { 
      InitializeComponent(); 
      finishingThread = false; 
      finished = false; 
      thread = new Thread(Run); 
      thread.Start(); 
     } 

     protected override void OnClosing(CancelEventArgs e) 
     { 
      finishingThread = true; 
      if(!finished) e.Cancel = true; 
      base.OnClosing(e); 
     } 

     private void Run() 
     { 
      while(!this.Visible); 
      while(this.Visible && !finishingThread) 
      { 
       this.Invoke((ThreadStart)delegate() 
       { 
        textBox1.Text = "Yahoo"; 
       }); 
       Thread.Sleep(100); 
      } 
      finished = true; 
      this.Invoke((ThreadStart)delegate() 
      { 
       this.Close(); 
      }); 
     } 
    } 
} 
+0

Mon thread d'exécution a un sommeil quelque part, et il fait plus que simplement attendre que cette fonction soit retournée. En substance, la forme principale met à jour, mais seulement quand elle dépasse la fonction. –

Questions connexes