IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
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 expérimenté
    Avatar de Gouyon
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Loiret (Centre)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 1 076
    Points : 1 521
    Points
    1 521
    Billets dans le blog
    5
    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 et Apple c'est pas mieux
    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
    1 044
    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 : 1 044
    Points : 2 187
    Points
    2 187
    Billets dans le blog
    1
    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 expérimenté
    Avatar de Gouyon
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Loiret (Centre)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 1 076
    Points : 1 521
    Points
    1 521
    Billets dans le blog
    5
    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 et Apple c'est pas mieux
    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
    1 044
    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 : 1 044
    Points : 2 187
    Points
    2 187
    Billets dans le blog
    1
    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
    1 044
    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 : 1 044
    Points : 2 187
    Points
    2 187
    Billets dans le blog
    1
    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 expérimenté
    Avatar de Gouyon
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Loiret (Centre)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 1 076
    Points : 1 521
    Points
    1 521
    Billets dans le blog
    5
    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 et Apple c'est pas mieux
    Mon modeste site et mes modestes oeuvres sont
    Rémi

  7. #7
    Membre chevronné
    Avatar de DjmSoftware
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Mars 2002
    Messages
    1 044
    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 : 1 044
    Points : 2 187
    Points
    2 187
    Billets dans le blog
    1
    Par défaut
    Salut,
    Peux-tu me faire part de ton expérience avec les Threads Queues.
    J’ai pour ma part modifier avec succès pas mal de mes grammes fonctionnant auparavant avec la méthode synchronize
    Cdlt
    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

  8. #8
    Membre expérimenté
    Avatar de Gouyon
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Loiret (Centre)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 1 076
    Points : 1 521
    Points
    1 521
    Billets dans le blog
    5
    Par défaut
    Désolé pour la réponse tardive mais j'ai du basculer sur un autre sujet. J'ai fait la modification sur mon programme et je dirais qu'après les premiers tests je ne constate pas de grosse différence au niveau des performances.
    Par contre ta méthode est plus intéressante dans la mesure ou il est possible de passer des paramètres ce qui n'est pas le cas avec Synchronize.
    Conclusion j'utilise ta méthode maintenant.
    Il y a des jours où j'éprouve une haine profonde envers microsoft et Apple c'est pas mieux
    Mon modeste site et mes modestes oeuvres sont
    Rémi

  9. #9
    Membre chevronné
    Avatar de DjmSoftware
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Mars 2002
    Messages
    1 044
    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 : 1 044
    Points : 2 187
    Points
    2 187
    Billets dans le blog
    1
    Par défaut
    merci pour ton retour
    la différence fondamentale entre synchronize et les queues réside dans le fait que les queues utilisent un mode asynchrone, quelque peu identique à l'emploi de PostMessage.
    j'ai modifié beaucoup de mes applications qui utilisait synchronize au profit des queues qui quoique un peu plus difficile à mettre en œuvre sont plus efficientes

    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

  10. #10
    Membre actif Avatar de Argol_Medusa
    Homme Profil pro
    Ingénieur Radiofréquences
    Inscrit en
    Août 2005
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur Radiofréquences
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 208
    Points : 242
    Points
    242
    Par défaut
    Effectivement je n'avais jamais pensé à ça. Perso je le fais tout le temps avec mes grosses pattounes en claquant un gros :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TThread::Synchronize(TThread::CurrentThread,BMP2JPG);
    en plein milieu du ServeurExecute

    Ouai c'est moche mais ça marche bien de mon coté, je n'ai jamais eut de souci avec en tout cas.


    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
    void __fastcall TForm1::IdTCPServer1Execute(TIdContext *AContext)
    {
    	unsigned char Commande = AContext->Connection->Socket->ReadByte();
    	// commande "Envoyer une photo"
     
    	if (Commande == 0x02)
    	{
    		TThread::Synchronize(TThread::CurrentThread,BMP2JPG);
    		jpg->CompressionQuality=50;
    		jpg->SaveToStream(RAM);
    		RAM->Seek(0,0);
    		AContext->Connection->Socket->Write( (unsigned int) RAM->Size);
    //		this->Memo1->Lines->Add(RAM->Size);
    		AContext->Connection->Socket->Write(RAM);
    		RAM->Clear();
    	}
    	else if (Commande == 0x03) // commande "envoyer une vidéo de 25 images"
    	{
    		for (int i = 0; i < 25; i++)
    		{
    			Sleep(1000/25);
    			TThread::Synchronize(TThread::CurrentThread,BMP2JPG);
    			jpg->CompressionQuality=1;
    			jpg->SaveToStream(RAM);
    			RAM->Seek(0,0);
    			AContext->Connection->Socket->Write( (unsigned int) RAM->Size);
    //			this->Memo1->Lines->Add(RAM->Size);
    			AContext->Connection->Socket->Write(RAM);
     
    			RAM->Clear();
    		}
    	}
     
    }
    Désolé, on savait pas que c'était impossible, alors on l'a fait

  11. #11
    Membre chevronné
    Avatar de DjmSoftware
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Mars 2002
    Messages
    1 044
    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 : 1 044
    Points : 2 187
    Points
    2 187
    Billets dans le blog
    1
    Par défaut
    Salut,
    Sans vouloir faire une pub exagéré pour l'utilisation de TThread::Queue:
    cependant...:
    ca simplifie considérablement la tâche:
    j'ai réalisé un traitement centralisé des Traces émises par mes différents forms. ainsi que le traitement des messages d'erreurs retournées
    Avantage:
    Affichage dans un seul composant, (TMemo) de ma form principale et non pas dans chaque fiche de tous les messages d'erreurs de mon application,
    je fais de même pour la gestion centralisée des Traces (Log)
    Toutes les fiches que tu utilise dans une application sont composées également d'un ou plusieurs Threads ce qui rend très intéressant l'emploi de TThread::Queue

    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

Discussions similaires

  1. problème de synchronisation de thread
    Par youp_db dans le forum Entrée/Sortie
    Réponses: 2
    Dernier message: 11/10/2006, 11h34
  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, 13h11
  3. Problème de synchronisation...
    Par sankookai dans le forum MFC
    Réponses: 10
    Dernier message: 16/02/2005, 14h03
  4. [C#] Problème de synchronisation de combobox
    Par WwiloO dans le forum Windows Forms
    Réponses: 3
    Dernier message: 20/12/2004, 19h56
  5. Problème de synchronisation dans un JTextArea
    Par wutang dans le forum Composants
    Réponses: 3
    Dernier message: 21/06/2004, 15h06

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