begin process at 2010 02 09 20:36:06
  Trouver un code source :
 
dans
 
Accueil > Forum > 

Delphi

 > 

Algorithme

 > 

Autre

 > 

Thread : Synchronize Bloqué !!!!


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

Thread : Synchronize Bloqué !!!!

jeudi 10 août 2006 à 15:53:54 | Thread : Synchronize Bloqué !!!!

picolo5

Membre Club

Bonjour à tous !

Je dev un projet qui utlise une dll. Cette dll me permet de me connecter à un serveur et de recuperer une trame.

J ai donc mis en place un thread pour executer l "ecoute" du serveur :

----------------------------------------------------------------------------------------------------------------------------------
unit Unit2;

interface

uses
  Classes,Windows,Unit1 ;


type
  MonThread = class(TThread)
  private
    FForm : TForm1;
    { Déclarations privées }
  protected
    procedure Execute; override;
    procedure Traiter;
    procedure Sync;
    public
    constructor Create(Form : TForm1);

  end;

implementation

{ Function importées de la DLL}
function OpenSession(loggin : PChar; pswd : PChar): integer; StdCall; external 'Test.dll';
function Init(portServSPAD : integer ;portServTPAD : integer): integer; StdCall; external 'Test.dll';
function CloseSession(): integer; StdCall; external 'Test.dll';
function GetMessage(messages : PChar): integer; StdCall; external 'Test.dll';

 

{ MonThread }

var
    trame : array[0..1024] of char;
    LaTrame : string;

procedure MonThread.Traiter;
begin
   FForm.Ed_Loggin.Text := 'Grrrrrrrr';
   FForm.TraiterTrame(Trame);
end;


constructor MonThread.Create(Form: TForm1);
  begin
    inherited Create(False);
    FForm := Form;
    FreeOnTerminate := True;
  end;

procedure MonThread.Sync();
begin
Synchronize(Traiter);
End;

procedure MonThread.Execute;
var
  test : boolean;
  ret : integer;
  SPass,SLoggin : string;
begin
  while not Terminated do
    begin
    sleep(1500);
    ret := GetMessage(trame);

    if ret <> 0 then
      begin
      // Gerer la reconnection
      Init(3002,3001);
      CloseSession();
      Sleep(5);
      SPass := 'EMULOP01';
      SLoggin := 'EMULOP01';
      OpenSession(PChar(SPass),PChar(SLoggin));
      end
    else
      begin
      LaTrame := String(trame);
      if LaTrame <> '' then
      }
      Sync();
      //Form1.TraiterTrame(String(Trame));  // Je triche en virant les // et en desactivant Sync(),  ca marche mais ce n est
                                                                 //     pas  'securisé'
      end;
    end;
end;

end.
----------------------------------------------------------------------------------------------------------------------------------


Je lance mon app (une form avec un bouton pour lancer le thread, la procedure TForm1.TraiterTrame(Trame))

puis je click sur le bouton de lancement du thread :

MyThread:= MonThread.Create(Form1);


Le thread se lance, fait son travail et :

-Si ma souris est sur la form, le synchronize du thread se fait correctement !
-Si ma souris est hors de la form, le thread ne rentre pas ds la procedure à synchronize tant que je ne rentre pas ma souris sur la form. (si je met un point d arret à l entree de Traiter() il n est atteind que ds le cas ou ma souris reviens sur la form !!)

J ai ajouté le passage de la form a mon thread en pensant que le prob venait de la.... mais non :(
J ai essayer de virer tout le code 'superflu' de la methode execute en ne laissant que le synchronize, mais c est idem.

Si je supprime le Sync() et que je le remplace par : Form1.TraiterTrame(String(Trame)); 
cela marche correctement, mais n est pas 'Sécurisé' ??

Au secours !!!!!

Merci ;)

jeudi 10 août 2006 à 16:13:13 | Re : Thread : Synchronize Bloqué !!!!

Loda

Membre Club
salut, je m'y connais pas trop en thread, mais c'est pas: TThread.Synchronize(Sender,methode) plustot? bon code,
jeudi 10 août 2006 à 16:45:51 | Re : Thread : Synchronize Bloqué !!!!

picolo5

Membre Club

Il me semble bien que j utilise la bonne declaration de Synchronize, je ne trouve nulle part de version TThread.Synchronize(Sender,methode) uniquement TThread.Synchronize(methode)

jeudi 10 août 2006 à 20:22:50 | Re : Thread : Synchronize Bloqué !!!!

Forman

Salut, Peut-être que le problème vient de la façon dont tu lances le thread. Le code que tu as posté me parait tout à fait valide, mais il faudrait que tu postes aussi le source de la form pour voir s'il n'y a pas un problème là (par exemple si tu lances le thread dans un événement, et que tu fais un WaitFor dans l'événement).
jeudi 10 août 2006 à 20:33:44 | Re : Thread : Synchronize Bloqué !!!!

Forman

Après avoir relu la façon dont Borland a implémenté la méthode Synchronize, j'ai lu que lorsque l'application entre dans un état IDLE (en attente de messages), elle crée une procédure WakeMainThread qui fait ceci: procedure TApplication.WakeMainThread(Sender: TObject); begin PostMessage(Handle, WM_NULL, 0, 0); end; Cette procédure est appelée (si assignée, donc si l'application est en mode idle) par tout thread souhaitant se synchroniser. Je me souviens avoir rencontré un problème semblable sous windows millenium: l'événement OnIdle de l'application n'était pas appelé correctement. Tu as quelle version de Windows? Sinon, le problème peut venir de ta DLL. Que se passe-t-il lorsque tu remplaces les fonctions importées par des fonctions bidons et que tu ne charges pas la DLL?
jeudi 10 août 2006 à 23:35:43 | Re : Thread : Synchronize Bloqué !!!!

Delphiprog

Administrateur CodeS-SourceS
Réponse acceptée !
Salut à tous, amis des threads

A priori, en épurant ton code et en restructurant, voici le code qui fonctionne et qui est aussi proche possible de ce que tu nous décris.
Avant tout, pour éviter les références croisées entre l'unité de la fiche et celle du thread, j'ai ajouté une troisième unité nommée...Unit3 :

unit Unit3;

interface

type
  TTrame = array[0..1024] of char;

implementation

end
.

Ce qui permettra l'utilisation d'un type commun entre la méthode TraiterTrame de la fiche et le membre de la classe TMonThread (noter l'ajout du 'T' pour respecter les conventions standards).
Voici un extrait du code de la fiche, contenu dans Unit1_1.pas :
var
  MonThread: TMonThread = nil;

{ TForm1 }

procedure TForm1.TraiterTrame(Trame: TTrame);
begin
  Label1.Caption := Trame;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  //pas plus d'1 thread à la fois svp
  if MonThread = nilthen
    MonThread := TMonthread.Create(Self);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  if MonThread <> nilthen
    MonThread.Terminate;
  MonThread :=
nil;
end;

Puis, le meilleur pour la fin :

unit Unit2;

interface

uses
  Classes, Windows, Unit1_1, Unit3;

type
  TMonThread = class(TThread)
 
private
    FForm: TForm1;
    Trame: TTrame;
   
procedure Fin;
 
protected
    procedure Execute; override;
   
procedure Traiter;
   
procedure WhenTerminated(Sender: TObject);
 
public
    constructor Create(Form: TForm1);
 
end;

implementation

uses
SysUtils;

{ TMonThread }

procedure TMonThread.Traiter;
begin
  FForm.Ed_Loggin.Text := 'Test de trame...';
  FForm.TraiterTrame(Trame);
end;

constructor TMonThread.Create(Form: TForm1);
begin
  inherited Create(False);
  FForm := Form;
  OnTerminate := WhenTerminated;
  FreeOnTerminate := True;
end;

procedure TMonThread.Execute;
var
  ret: integer;
begin
  Ret := 0;
 
//s'arrêtera automatiquement au bout de 20 secondes
  whilenot Terminated and (Ret < 20) do
  begin
    sleep(1000);
    inc(ret);
    StrPCopy(Trame,
'Envoi de la trame ' + IntToStr(Ret));
   
if Trame[0] <> #0then
      Synchronize(Traiter);
 
end;
end;

procedure TMonThread.WhenTerminated(Sender: TObject);
begin
  Synchronize(Fin);
end;

procedure TMonThread.Fin;
begin
  FForm.Ed_Loggin.Text := 'Terminé !';
end;

end.

En dehors de l'ajout d'une méthode pour bien pouvoir observer l'arrêt du thread sur la fiche, la variable LaTrame a été avantageusement remplacée par le tableau de caractères. J'ai trouvé qu'il était inutile de dupliquer d'un PChar dans une string.

Ce code fonctionne, avec ou sans souris au dessus de la fiche, la fenêtre en arrière plan comme en avant plan mais également quand on déplace la fenêtre en cours d'exécution.
Teste le.
Si tout fonctionne aussi chez toi, c'est que ton problème vient soit de la dll, soit d'ailleurs.

May Delphi be with you !

Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
jeudi 31 août 2006 à 13:52:31 | Re : Thread : Synchronize Bloqué !!!!

picolo5

Membre Club
Merci pour toutes ces reponses, je me remet sur ce projet aujourd'hui, je pense que ce post n'est pas encore terminé ! ;)


Cette discussion est classée dans : form, end, thread, procedure, trame


Répondre à ce message

Sujets en rapport avec ce message

pb a creer un exe avec la principal form invisible [ par Winniez ] J'ai voulu au demarrage de exe afficher une autre form que la form principal. a l'execution sa me met une erreur, apres g mis le meme code dans un bou Réccupérer des données sur un autre Unit [ par m_cyril1 ] J'ai fait un petit programme, celui-ci mémorise des chiffres entier sur une première form et sur la deuxième le résultat de la somme des chiffres s'af Delphi vers C++ [ par Roulio52 ] Salut à tous !Je suis un petit débutant en C++,et je commence à créer un petit paint sous borland.J'ai un code DELPHI qui pourrait m'être super utile Aide INDY Choix du thread lors du WriteLn [ par Nostaroth ] Bonjour! Alors voila, je voudrai realisé un Chat Multi-Client et je voudrai que depuis mon serveur, je puisse selectioné le Thread a qui envoyé le mes Classe TThread dans composant, liaison entre deux instances ? [ par Bacterius ] Bonjour ! Alors voilà un problème - j'essaye de faire un timer très précis : malheureusement celui-ci a besoin d'un thread pour fonctionner ! Je cherc thread & dll -> Exception [ par WSTBoss ] Bonjour à tous,j'ai une dll qui contient un thread, tout ce passe bien le thread marche comme il faut mais cependant lors du dechargement de la dll pa le Thread dans un Form [ par notrica ] Salut j'ai utiliser le thread dans le form. au lancement lorsque il exécuter "FormActivate(Sender: TObject)", il termine et affiche un message d'inter stingGrid et dbgrid [ par zerargui ] j'ai pris le programme de delphiprog qui est dessousmais à la place d'une base de données Dbase(.dbf) j'ai utilisé une base paradox(.db)alors le progr Dbgrid et index [ par zerargui ] j'ai pris un petit programme de Delphiprog en le modifiant par la lecture des indexes de DBase .DBF par indexex de base Paradox  .db tous s'affiche no Gestion de sa trayIcone [ par Michel34 ] Salut a toutes et tous , voila en premier je met le code et ensuite je vous donne mon soucis.UNIT UMain; INTERFACE USES  Windows,  Messages,  SysU


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Février 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,811 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales