3 votes

C# BackgroundWorker et problèmes de port Com

D'accord. J'ai un programme qui surveille 2 ports COM. Un est connecté à une balance et l'autre est connecté à une carte modbus.

Mon problème se situe dans le port COM attaché à la carte modbus. Mon programme lit un capteur (sur la carte modbus) toutes les 100MS. Il renvoie un 0 ou un 1 (via le port COM) pour déterminer si le capteur est bloqué. Si c'est le cas, un signal est envoyé sur le port à la carte.

Mon problème est que je ne peux pas arrêter de surveiller le capteur, mais je dois m'assurer que le port com n'est pas utilisé avant d'envoyer mon autre signal.

La routine qui surveille le capteur est sur un thread BackgroundWorker. Une fois que le capteur est déclenché, un autre thread est créé pour envoyer un signal à la carte modbus. Je dois donc mettre en pause le "thread du capteur" pendant que j'envoie un signal à la carte. Comment pourrais-je procéder?

Rappelez-vous que c'est un BackgroundWorker, donc Join Thread n'est pas une option.

Voici mon code:

private void SensorThread_DoWork(object sender, DoWorkEventArgs e)
    {
        if (SensorThread.CancellationPending == true)
            e.Cancel = true;
        else
        {
            ReadSensor();
        }    
    }

Le RunWorkerCompleted pour ce thread redémarre simplement le thread. Le thread suivant surveille constamment le "statut du capteur" pour savoir quand le capteur est bloqué:

public void ScaleThread_DoWork(object sender, DoWorkEventArgs e)
    {
        if (ScaleThread.CancellationPending == true)
        {
            e.Cancel = true;
        }
        else
        {
            //le capteur est bloqué
            if (sensorstatus == 0)
            {
                ReadScale();
                prevgate = gate;
                gate = DetermineGate();
                //Enregistrer les données();
                SetOpenDelay();
                SetDuration();
                //aucun portail n'a été sélectionné, la viande est hors de portée, sort de l'extrémité
                if (gate == 0)
                {
                    txtStatus.Invoke(new UpdateStatusCallback(UpdateStatus), new object[] { meatweight.ToString() + 
                                                                                    "lbs est hors de portée"});
                }
                else
                {
                    //cela déclenche un thread pour envoyer un signal à la carte modbus
                    gateTimer.Start();
                }
            }
        }
    }

Le RunWorkerCompleted pour cela redémarre ce thread, en faisant une boucle

5voto

Ian Mercer Points 19271

Créer un seul fil responsable de TOUTES les opérations d'envoi. Mettez en place une file d'attente qui alimente ce fil avec des messages à envoyer au périphérique. Vous pouvez utiliser le nouveau BlockingCollection pour implémenter cela facilement.

OU, en utilisant TPL, créez un TaskScheduler avec un degré de parallélisme limité à 1 comme indiqué ici:- http://msdn.microsoft.com/en-us/library/ee789351.aspx

Maintenant, vous pouvez simplement lancer des tâches pour envoyer au périphérique et elles s'exécuteront séquentiellement.

Sauf s'il y a un besoin de communiquer des informations entre l'expéditeur et le destinataire, je mettrais en œuvre l'opération de lecture sur son propre fil séparé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X