2009-09-07 8 views
1

Je travaille sur le projet et j'ai un problème avec le filetage et la mise à jour de l'interface utilisateur. J'ai lu beaucoup de post sur le web et ce site, mais je n'ai pas trouvé de réponse à mon problème.Formulaire de mise à jour C# à partir du filetage et de la classe

Je fais un programme qui attend quelques données UDP sur le port XXXX. Boucle dans le fil séparé. Quand les données arrivent, il extrait des informations et les met dans un tampon, et retourne attendre une autre donnée. Une autre routine de thread attend les données dans le tampon et l'envoie au courrier électronique. En raison de la fonctionnalité et de la conception de code j'ai Form1 classe (UI) - fil principal, Class2 (rutine pour lire UDP et extraire des données) - fil secodn, Class3 (lecture tampon et envoyer courrier) - troisième thread, Class4 (file d'attente buffer (lire, écrire, supprimer des items)) ...

Le problème est que lorsque je veux mettre à jour l'interface utilisateur de l'une des classes, j'ai BufferOwerflow Exception ... C'est logique car je dois d'abord faire instance si Class pour démarrer le thread et dans la classe I doit faire une instance de Form pour transmettre des données, puis nous avons une boucle infinie.

Tous les messages que j'ai trouvés ici concernent la mise à jour de l'interface utilisateur à partir du thread mais dans la même classe. Je comprends le problème de la pile et de la boucle à cause des instances. Je ne veux tout simplement pas avoir une grande classe principale avec une énorme quantité de code à l'intérieur ...

Est-il possible de mettre à jour la forme principale d'une autre classe et une routine de threading à l'intérieur?

J'écris un exemple de la tête (ça ne marche pas) juste pour avoir une idée de ce dont je parle.

namespace ThreadUIClass 
{ 
    public delegate void updateTextBoxDelegate(string text); 

    public partial class Form1 : Form 
    { 
     void updateTextBox(string text) 
     { 
      textBox.Text = text; 
     } 
     public Form1() 
     { 
      InitializeComponent(); 
      Go(); 
     } 
     public void Go() 
     { 
      textBox.Text = "START"; 
      DoWork dW = new DoWork(); //<= instance of work class 
      Thread myThread = new Thread(dW.WorkInBeckground); 
      myThread.IsBackground = true; 
      myThread.Start(); 
     } 
    } 
    public class DoWork 
    { 
     public void WorkInBeckground() 
     { 
      while (true) //loop and wait for data 
      { 
       // Listen some ports and get data 
       // If (data==ok) update main UI textbox with status 
       Form1 myForm = new Form1(); //<= instance of main class 
       myForm.Invoke(new updateTextBoxDelegate(???updateTextBox), new object[] { "BUFFER LOADING..." }); 
       Thread.Sleep(1000); 
       // Continue looping..... 
      } 
     } 
    } 
} 

Répondre

3

Vous devez utiliser un objet threadstart et transmettre une référence à votre objet formulaire. Ce que vous êtes en train de faire est de créer une nouvelle référence à votre mainform, qui à son tour déclenche un fil, qui à son tour fait la même chose. Il suffit donc d'utiliser un objet paramaterizedthreadstart pour lancer votre thread, en passant "this" et tout devrait bien se passer.

MSDN ParameterizedThreadStart

+0

Je vais essayer de faire ça ... merci! –

2

ne serait pas préférable d'utiliser le BackgroundWorker pour y parvenir? Il y a un très bon example here. Cette classe est prise en charge par l'interface utilisateur et vous pouvez appeler directement les composants de l'interface utilisateur.

+0

Mais vous devez toujours dire à BackgroundWorker que cela doit aller dans la classe de travail? Et vous devez faire une instance de cette classe .... –

Questions connexes