Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++Builder Discussion :

Problème de synchronisation


Sujet :

C++Builder

  1. #1
    Membre éprouvé
    Avatar de Gouyon
    Homme Profil pro
    Développeur informatique
    Inscrit en
    novembre 2003
    Messages
    827
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : novembre 2003
    Messages : 827
    Points : 994
    Points
    994
    Par défaut Problème de synchronisation
    Bonjour

    J'ai fait un serveur TCP avec le composant TidTCPServer dans une application FMX. Dans la méthode ServeurExecute je lit les données reçues et j'en affiche une partie dans une liste box.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    void __fastcall TForm1::ServeurExecute(TIdContext *AContext) {
    	TByteDynArray pInfo;
    	unsigned short data[32 * 25];
    	char chaine[256];
    	try {
    		AContext->Connection->IOHandler->ReadBytes(pInfo, 1856, false);
    		memcpy(chaine, &pInfo[0], 256);
    		memcpy(data, &pInfo[256], 32*25*2);
    		String rep = "";
    		int n = 0;
    		while (n < 256 && chaine[n] != 0) {
    			rep += chaine[n];
    			n++;
    		};
    		updateListe(rep);//rafraichissement de la liste
     
    	}
    	catch (const Exception& e) {
    		// AFAIRE
    	}
    }
    Manifestement la fonction d'affichage ci dessous ne supporte pas d'être accédé par un thread. Car j'ai régulièrement des exceptions qui normalement n'ont pas lieu d'être

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    void __fastcall TForm1::updateListe(String rep) {
    	lbReseau->Items->Add(rep);
    	if (lbReseau->Items->Count > 10)
    		lbReseau->Items->Delete(0);
    }
    Pour éviter cela, j'ai vu qu'il fallait que j'utilise la méthode Synchronize mais je n'arrive pas à la mettre en oeuvre.

    En effet j'ai voulu utiliser TIdThread.Synchronize mais il ne veux pas compiler cette ligne.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    TIdThread::Synchronize((TThreadMethod)&updateListe(rep));
    Voici l'erreur E2109 Ce n'est pas un type autorisé

    Une idée?
    Il y a des jours où j'éprouve une haine profonde envers microsoft
    Venez vous défouler ici ou c'est amusant
    Mon modeste site et mes modestes oeuvres sont
    Rémi

  2. #2
    Membre chevronné
    Avatar de DjmSoftware
    Homme Profil pro
    Responsable de compte
    Inscrit en
    mars 2002
    Messages
    859
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Responsable de compte
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : mars 2002
    Messages : 859
    Points : 1 856
    Points
    1 856
    Par défaut
    Salut
    ta manière d'utiliser ce composant me semble incorrecte
    je te conseille de regarder le lien suivant:http://codeverge.com/embarcadero.cpp...pserve/1080046
    ou en delphi un code plus complet https://silverpeacock.wordpress.com/...nt-components/
    bien cordialement
    vous trouverez mes tutoriels à l'adresse suivante: http://djmsoftware.developpez.com/
    je vous en souhaite une excellente lecture ...

    A lire : Les règles du forum

  3. #3
    Membre éprouvé
    Avatar de Gouyon
    Homme Profil pro
    Développeur informatique
    Inscrit en
    novembre 2003
    Messages
    827
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : novembre 2003
    Messages : 827
    Points : 994
    Points
    994
    Par défaut
    Merci pour ces exemples.
    Malheureusement ils ne fonctionnent pas avec FMX.
    L'include #include <IdAntiFreeze.hpp> bloque la compilation avec cette erreur [ilink32 Erreur] Fatal: Impossible d'ouvrir le fichier 'VCL.FORMS.OBJ'
    Sinon j'ai trouvé cette solution:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    //appel de la fonction de mise à jour de la liste des messages
     TThread::Synchronize(NULL, (TThreadMethod)&updateListe);
    fonction de mise à jour des messages
    TClientTCP est un objet créé à la connexion et contient les informations à traiter qui on été reçue dans la fonction ServeurExecute.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    void __fastcall TScarboMainForm::updateListe() {
    	TClientTCP *clx = NULL;
    	String rep;
     
    	for (int n = 0; n < pClients->Count; n++) {
    		clx = (TClientTCP*)pClients->Items[n];
    		rep = clx->getInfo();
    		if (!rep.IsEmpty()) {
    			lbReseau->Items->Add(rep);
    			if (lbReseau->Items->Count > 10)
    				lbReseau->Items->Delete(0);
    		}
    	}
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void __fastcall TScarboMainForm::ServeurConnect(TIdContext *AContext) {
    	TClientTCP *cl = new TClientTCP(0, AContext);
    	pClients->Add(cl);
    }
    La fonction ServeurExecute
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
     
    void __fastcall TScarboMainForm::ServeurExecute(TIdContext *AContext) {
    	TByteDynArray pInfo;
    	bool trouve = false;
    	int nctx = 0;
    	char chaine[256];
    	TClientTCP *clx = NULL;
    	try {
     
    		while (!trouve && nctx < pClients->Count) {
    			clx = (TClientScarbo*)pClients->Items[nctx];
    			trouve = (clx->getContext() == AContext);
    			nctx++;
    		}
    		if (trouve) {
    			if (clx->getID() == 1 || clx->getID() == 2)
    				AContext->Connection->IOHandler->ReadBytes(pInfo, 17440, false);
    			if (clx->getID() == 3)
    				AContext->Connection->IOHandler->ReadBytes(pInfo, 786688, false);
    			if (clx->getID() == 0)
    				AContext->Connection->IOHandler->ReadBytes(pInfo, 256, false);
     
    			memcpy(chaine, &pInfo[0], 256);
    			String lrep = "";
    			int n = 0;
    			while (n < 256 && chaine[n] != 0) {
    				lrep += chaine[n];
    				n++;
    			}
    			int deb = lrep.Pos("IDENTIFIANT");
    			if (deb > 0) {
    				String num = lrep.SubString(deb + 8, 1);
    				int ref = num.ToInt();
    				if (ref == 1 || ref == 2)
    					clx->setDataBuff(64*64*4);
    				if (ref == 3)
    					clx->setDataBuff(512*512*4);
    				clx->setID(ref);
    				clx->setON(true);
    				TThread::Synchronize(NULL, (TThreadMethod)&updateLed);
    			}
    			else {
    				void *data = clx->getDataBuff();
    				clx->setInfo(lrep);
    				memcpy(data, &pInfo[256], clx->getTailleData());
    				TThread::Synchronize(NULL, (TThreadMethod)&updateListe);
    				TThread::Synchronize(NULL, (TThreadMethod)&updateImg);
    			}
     
    		}
    	}
    	catch (const Exception& e) {
    		// AFAIRE
    	}
    }
    Il y a des jours où j'éprouve une haine profonde envers microsoft
    Venez vous défouler ici ou c'est amusant
    Mon modeste site et mes modestes oeuvres sont
    Rémi

  4. #4
    Membre chevronné
    Avatar de DjmSoftware
    Homme Profil pro
    Responsable de compte
    Inscrit en
    mars 2002
    Messages
    859
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Responsable de compte
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : mars 2002
    Messages : 859
    Points : 1 856
    Points
    1 856
    Par défaut
    Salut
    Merci pour le code fournit
    en fait l'include #include <IdAntiFreeze.hpp> n''est pas nécessaire dans ce cas
    il y aura peut-être d'autres erreurs

    par ailleurs l'utilisation de synchronize est déconseillé car cette méthode est symchrone et peut bloqué le thread, il est préférable d'utiliser la méthode Queue qui est asynchrone ou un bon vieux PostMessage qui utilise la boucle de Message Windows

    bien cordialement
    vous trouverez mes tutoriels à l'adresse suivante: http://djmsoftware.developpez.com/
    je vous en souhaite une excellente lecture ...

    A lire : Les règles du forum

  5. #5
    Membre chevronné
    Avatar de DjmSoftware
    Homme Profil pro
    Responsable de compte
    Inscrit en
    mars 2002
    Messages
    859
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Responsable de compte
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : mars 2002
    Messages : 859
    Points : 1 856
    Points
    1 856
    Par défaut
    Salut,
    pour revenir à mon précédent post concernant l'utilisation de TThread::Queue
    j'ai un peu investigué et voici une solution que je trouve élégante
    pour travailler avec les méthodes Anonymes de Delphi avec C++ Builder il faut mettre en place tout une usine à Gaz en utilisant la classe TCppInterfacedObject

    exemple j'ai besoin envoyer sur le thread principal le nombre de clients connectés, ainsi que les Traces récoltées
    voici le code à utiliser

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
     
    class TNotifier : public TCppInterfacedObject<TThreadProcedure> {
    	int lValue;
    private:
    	TFMicroServer* form;
    public:
    	TNotifier(int ValSet, TFMicroServer* _form) : lValue(ValSet), form(_form) {}
    	INTFOBJECT_IMPL_IUNKNOWN(TInterfacedObject);
    	void __fastcall Invoke() {form->clients_connected->Text = lValue;}
    } ;
    // ---------------------------------------------------------------------------
     
    class TLogMessage : public TCppInterfacedObject<Classes::TThreadProcedure> {
    	String Msg;
    private:
    	TFMicroServer* form;
    public:
    	TLogMessage(String _Msg, TFMicroServer* _form) : Msg(_Msg), form(_form) {}
    	INTFOBJECT_IMPL_IUNKNOWN(TInterfacedObject);
     
    	void __fastcall Invoke() {form->messagesLog->Lines->Add(Msg);}
    } ;
     
    // ---------------------------------------------------------------------------
     
    //Ces méthodes seront utilisées de la manière suivante
     
    TThread::Queue(NULL, Classes::_di_TThreadProcedure(new TNotifier(nClients,
    	 this)));
    // notification du nombre de clients
     
    	UnicodeString Tmp("[" + p_sender + "]" + GetNow() + ":" + p_message);
    	TThread::Queue(NULL, Classes::_di_TThreadProcedure(new TLogMessage(Tmp,
    	  this)));
    }
    je suis à disposition en cas de renseignements complémentaires
    je joins un code complet fonctionnel en FMX

    bien cordialement
    Fichiers attachés Fichiers attachés
    vous trouverez mes tutoriels à l'adresse suivante: http://djmsoftware.developpez.com/
    je vous en souhaite une excellente lecture ...

    A lire : Les règles du forum

  6. #6
    Membre éprouvé
    Avatar de Gouyon
    Homme Profil pro
    Développeur informatique
    Inscrit en
    novembre 2003
    Messages
    827
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : novembre 2003
    Messages : 827
    Points : 994
    Points
    994
    Par défaut
    Merci pour le code je vais regarder ce que ça donne chez moi
    Il y a des jours où j'éprouve une haine profonde envers microsoft
    Venez vous défouler ici ou c'est amusant
    Mon modeste site et mes modestes oeuvres sont
    Rémi

Discussions similaires

  1. problème de synchronisation de thread
    Par youp_db dans le forum IO
    Réponses: 2
    Dernier message: 11/10/2006, 12h34
  2. [VB.net] Problème de synchronisation d'une base
    Par WriteLN dans le forum Windows Forms
    Réponses: 18
    Dernier message: 21/10/2005, 14h11
  3. Problème de synchronisation...
    Par sankookai dans le forum MFC
    Réponses: 10
    Dernier message: 16/02/2005, 15h03
  4. [C#] Problème de synchronisation de combobox
    Par WwiloO dans le forum Windows Forms
    Réponses: 3
    Dernier message: 20/12/2004, 20h56
  5. Problème de synchronisation dans un JTextArea
    Par wutang dans le forum Composants
    Réponses: 3
    Dernier message: 21/06/2004, 16h06

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo