2010-05-20 5 views
0

Salut J'utilise System.Timer.TimerComment puis-je laisser fil conducteur de suspendre et d'attendre la course System.Timer.Timer

Je reçois toujours NULL après l'exécution de mon programme et il ne fonctionne que si j'ajouter ceci. dormir (6000). Supposons que la raison est le fil principal se termine, mais le minuteur n'a pas fini ... Voici la classe et j'appelle la classe de mon formulaire principal.

Class class1 
{ 
    string finalResult = ""; 
    public string getNumber() 
    { 
    RunTimer(); 
    return finalResult; 
    } 
    pubic void RunTimer() 
    { 
    timer = new System.Timers.Timer(30000); 
    timer.Interval = 1000;   
    timer.Elapsed += new System.Timers.ElapsedEventHandler(cal); 
    timer.Start(); 
    } 
    private void cal(object sender,System.Timers.ElapsedEventArgs e) 
    { 
    finalResult += READFROMCOMPORT; 
    } 
} 
+0

Made it 30 secondes – Kelvin

Répondre

3

Pourquoi voudriez-vous utiliser une minuterie dans cette instance?

Si vous souhaitez que cette opération soit synchrone et attendez que le résultat final soit rempli, vous pouvez attendre 6 secondes avant de renvoyer READFROMCOMPORT.

EDIT: Si vous avez besoin du programme pour continuer à fonctionner, vous pouvez créer un événement de rappel auquel vous liez après avoir instancié la classe. Une fois que le temporisateur expire, vous pouvez augmenter l'événement de rappel et transmettre votre nouvelle valeur

EDIT 2: un moyen facile d'implémenter ce genre d'asynchrone consiste à utiliser un composant BackgroundWorker. l'arrière-plan a une méthode DoWork() qui contient votre code asynchrone, ainsi qu'un événement de rappel "RunWorkerCompleted" auquel vous pouvez vous abonner pour obtenir votre résultat asynchrone. Voir ici pour en savoir plus: http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

+0

Si je fais tout le sommeil du programme, l'utilisateur perd tous les controlls. Et le temps d'attente pourrait être plus de 6 secondes comme 30. Je ne pense pas que ce soit une bonne solution pour que le thread principal dorme pendant 30 secondes – Kelvin

+0

Ensuite, vous devez appeler le tout sur un autre fil, si vous le pouvez. Le thread principal est de retour dès que vous exécutez le minuteur, donc peu importe quoi, vous ne recevrez pas votre valeur, sauf si vous les gardez tous les deux hors du thread principal, de sorte que vous pouvez soit les combiner en un thread ou attendre 2 thread 3 (ce qui n'a évidemment pas beaucoup de sens) –

+0

vous pouvez également utiliser un rappel, voir mon edit –

3

Une bonne règle est de ne jamais utiliser Thread.Sleep dans le code de production. Sa présence indique généralement un mauvais filetage.

À la place, écoutez l'événement DataReceived du port COM.

+0

Mais les données seront envoyées au port COM en continu, c'est pourquoi j'ai besoin d'une minuterie pour écouter le port chaque seconde. – Kelvin

+0

Ou vous pouvez simplement répondre à 'DataReceived', qui se déclenche lorsque plus de données arrivent. Aucune minuterie nécessaire. –

0

Si vous appelez déjà GetNumber() à partir d'un thread distinct de l'interface graphique, abandonnez le temporisateur, effectuez le travail dans GetNumber() et le thread s'arrêtera de revenir plus tôt. Dans tous les cas, n'utilisez pas Thread.Sleep car il n'y a aucun moyen de le débloquer si nécessaire, ou si l'application se ferme. Utilisez plutôt Monitor.Wait, qui peut être débloqué avec Monitor.Pulse.

Questions connexes