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 :

Manipuler les items d'une collection depuis un thread secondaire


Sujet :

C++Builder

  1. #1
    Membre régulier
    Inscrit en
    Avril 2004
    Messages
    249
    Détails du profil
    Informations personnelles :
    Âge : 53

    Informations forums :
    Inscription : Avril 2004
    Messages : 249
    Points : 112
    Points
    112
    Par défaut Manipuler les items d'une collection depuis un thread secondaire
    Bonjour,

    Le thread principal de mon programme crée une collection et en exploite le contenu.
    Le remplissage de cette collection pouvant être long (données provenant de requêtes http), j'ai créé un thread secondaire pour gérer la récupération des données.
    J'ai adopté un concept qui fonctionne (sur ma machine de dev, en version debug) mais je ne suis pas sûr que ce soit vraiment thread-safe.
    Que pensez-vous du fonctionnement décrit ci-dessous ? :

    MainThread :
    - création de la collection
    - création d'un objet sdk (permet l'accès aux données)
    - création du thread en lui passant en paramètres dans le constructeur de la classe un pointeur sur la collection et un autre sur l'objet sdk

    Thread secondaire
    - dans le constructeur, copie des pointeurs passés en paramètre dans des pointeurs locaux
    - dans la méthode execute(), appel des différentes fonctions permettant de récupérer les données à l'aide du pointeur local sur l'objet sdk
    - ajout des items directement dans la collection à l'aide du pointeur local sur la collection

    Je précise qu'il n'y a qu'un seul thread secondaire et que les données ajoutées à la collection par le thread secondaire ne sont exploitées par le thread principal qu'une fois le thread terminé.

    Voilà en résumé le code utilisé :

    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
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    //-----------------------------------------------------------------------------
    threadconfig.h
    //-----------------------------------------------------------------------------
    class TThreadGetConfig : public TThread
    {
    private:
    	pSDK FSDK;
    	pControllersCollection FSubControllers;
     
    protected:
    	void __fastcall Execute();
     
    public:
    	__fastcall TThreadGetConfig(pSDK paramSDK, pControllersCollection paramSubControllers);
    };
     
     
    //-----------------------------------------------------------------------------
    threadconfig.cpp
    //-----------------------------------------------------------------------------
     
    __fastcall TThreadGetConfig::TThreadGetConfig(pSDK paramSDK, pControllersCollection paramSubControllers)
    : TThread(true)
    {
    	FSDK = paramSDK;
    	FSubControllers = paramSubControllers;
     
    	FreeOnTerminate = true;
    }
     
    void __fastcall TThreadGetConfig::Execute()
    {
    	ReturnValue = (GetSiteConfig() ? 0:1);
    	Terminate();
    }
     
    bool __fastcall TThreadGetConfig::GetSiteConfig()
    {
    	std::vector<TSDK_ConfigData>::iterator ptr_subctrl;
       ...
     
    	try
    	{
    		if (!SDK->Connected)
    			throw Exception("sdk error");
     
    		//get data from sdk calls
    		...
     
    		for (ptr_subctrl = subcontrollers.begin(); ptr_subctrl < subcontrollers.end(); ptr_subctrl++)
    		{
    			pControllerItem subctrl_item = (pControllerItem)SubControllers->Add();
    			subctrl_item->Data->Id = ptr_subctrl->id;
    			subctrl_item->Data->Serial = ptr_subctrl->serial;
    			...
    		}
     
    		return true;
    	}
    	catch(...)
    	{
    	}
     
    	return false;
    }
     
     
    //-----------------------------------------------------------------------------
    main.h
    //-----------------------------------------------------------------------------
     
    class TfrmMain : public TForm
    {
    __published:
       ...
    private:
       TThreadGetConfig *thrdGetConfig;
    	pSDK FSDK;
    	pControllersCollection FSubControllers;
    }
     
     
    //-----------------------------------------------------------------------------
    main.cpp
    //-----------------------------------------------------------------------------
     
    __fastcall TfrmMain::TfrmMain(TComponent* Owner)
    	: TForm(Owner)
    {
    	FSubControllers = new TControllersCollection(NULL);
    	FSDK = new TSDK();
    }
     
    void __fastcall TfrmMain::StartThread()
    {
    	thrdGetConfig = new TThreadGetConfig(
    			this->SDK,
    			this->SubControllers);
     
    	thrdGetConfig->Resume();
    }
    Ce code est-il correct ?
    Merci pour votre aide
    _____
    __
    _

    Engi

  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,
    la classe thread a eu un certain nombre d'évolutions
    https://docwiki.embarcadero.com/Libr...Thread_Methods

    un certain nombre de méthode sont maintenant obsolète tel que


    StaticQueue (obsolète) public Exécute de manière asynchrone un appel de méthode dans le thread principal.
    StaticSynchronize (obsolète) public Exécute un appel de méthode dans le thread principal.
    Suspend (obsolète) public Interrompt l'exécution du thread. Suspend était destinée pour l'utilisation par les débogueurs et est obsolète dans RAD Studio XE, en 2010.

    pour ma part j'utilise les threads de manière asynchrone,
    je communique avec mon thread avec des events et le thread fait de même avec le thread Vcl ou FMX
    pour se faire

    j'utilse la métthode Queue du thread
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     
     
    TThread::Queue(NULL, Classes::_di_TThreadProcedure(new TLogMessage(FLogMsg,
    		Form9)));// message transmis au thread principal 
     
    TThread::Queue(NULL, Classes::_di_TThreadProcedure
    			(new THreadNotification(IsOK, Form9)));// notification faite au thread principal
     
    // form9 est ici la frome principale de mon application
    dans le thread principal:
    .
    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
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
     
     
    // ---------------------------------------------------------------------------
    /*
     Classes utilisées pour la lecture des queues des thread
     */
     
    // ---------------------------------------------------------------------------
    // retourne la valeur de retour d'un thread
    // 0 NOK et 1 OK
     
    // class TNotifier : public TCppInterfacedObject<TThreadProcedure> {
    // int lValue;
    // private:
    // TForm9* form;
    // public:
    // TNotifier(int ValSet, TForm9* _form) : lValue(ValSet), form(_form) {}
    // INTFOBJECT_IMPL_IUNKNOWN(TInterfacedObject);
    // void __fastcall Invoke() {}
    // } ;
    // ---------------------------------------------------------------------------
    // Retourne la valeur des traces générées par les thread
    class TLogMessage : public TCppInterfacedObject<Classes::TThreadProcedure> {
    	String Msg;
     
    private:
    	TForm9* form;
    	String LogTime;
     
    public:
    	TLogMessage(String _Msg, TForm9* _form) : Msg(_Msg), form(_form) {
    	}
    	INTFOBJECT_IMPL_IUNKNOWN(TInterfacedObject);
     
    	void __fastcall Invoke() {
    		AnsiString Funct, LineId, Resp, Status;
    		Funct = Msg.SubString(1, Msg.Pos(",") - 1);
    		Msg.Delete(1, Msg.Pos(","));
    		LineId = Msg.SubString(1, Msg.Pos(",") - 1);
    		Msg.Delete(1, Msg.Pos(","));
    		Resp = Msg.SubString(1, Msg.Pos(",") - 1);
    		Msg.Delete(1, Msg.Pos(","));
    		Status = Msg;
    		form->mLogger.FillStream(DateTimeToStr(Now()), Funct, LineId, Resp,
    			Status);
    		form->mLogger.Execute();
    	}
    };
     
    // ---------------------------------------------------------------------------
    class THreadNotification
    	: public TCppInterfacedObject<Classes::TThreadProcedure> {
    	bool lValue;
     
    private:
    	TForm9* form;
     
    public:
    	THreadNotification(bool ValSet, TForm9* _form)
    		: lValue(ValSet), form(_form) {
    	}
    	INTFOBJECT_IMPL_IUNKNOWN(TInterfacedObject);
     
    	void __fastcall Invoke() {
    		form->NotifyResult(lValue);
    	}
    };
     
    // ---------------------------------------------------------------------------
    class TErrorMessage : public TCppInterfacedObject<Classes::TThreadProcedure> {
    	String FErrorMsg1;
    	String FErrorMsg2;
     
    private:
    	TForm9* form;
     
    public:
    	TErrorMessage(String _EMsg1, String _EMsg2, TForm9* _form)
    		: FErrorMsg1(_EMsg1), FErrorMsg2(_EMsg2), form(_form) {
    	}
    	INTFOBJECT_IMPL_IUNKNOWN(TInterfacedObject);
     
    	void __fastcall Invoke() {
    		UnicodeString Ts;
    		Ts = DateTimeToStr(Now());
    		Ts += L" " + FErrorMsg1 + L" " + FErrorMsg2;
    		form->Memo1->Lines->Add(Ts);
    		if (!form->ChangeSize)
    			form->ChangeFormSize();
    		if (DataModule1->Enabled == true)
    			DataModule1->Enabled = false;
    	}
    };
     
    // ---------------------------------------------------------------------------
    class THreadNotificationExcel
    	: public TCppInterfacedObject<Classes::TThreadProcedure> {
    	bool lValue;
    	TStringList* mList;
     
    private:
    	TForm9* form;
     
    public:
    	THreadNotificationExcel(bool ValSet, TStringList* _mlist, TForm9* _form)
    		: lValue(ValSet), mList(_mlist), form(_form) {
    	}
    	INTFOBJECT_IMPL_IUNKNOWN(TInterfacedObject);
     
    	void __fastcall Invoke() {
    		if (lValue)
    			form->MFieldsContent->Assign(mList);
    		else
    			form->MFieldsContent->Clear();
    		form->NotifyResultExcel(lValue);
    	}
    };

    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. [VB]Retouver les clés des items d'une Collection, c'est possible ?
    Par marchand_de_sable dans le forum VBA Access
    Réponses: 11
    Dernier message: 19/12/2016, 16h44
  2. [Débutant] Portée d'une variable depuis un Thread secondaire
    Par BasicZX81 dans le forum VB.NET
    Réponses: 11
    Dernier message: 23/10/2013, 01h30
  3. BDC récupérer tous les items d'une application depuis le code
    Par tigrou2405 dans le forum Développement Sharepoint
    Réponses: 1
    Dernier message: 20/01/2011, 15h37

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