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

Langage Delphi Discussion :

[Débutant] Thread non bloquant


Sujet :

Langage Delphi

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    707
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 707
    Points : 777
    Points
    777
    Par défaut [Débutant] Thread non bloquant
    Bonjour,

    J'essaye de mettre en place un thread pour lancer des calculs très longs tout en gardant une interface "responsive" (?) mais j'avoue que je n'y connais rien ! Voilà ce que j'ai fait pour l'instant, problème: ça bloque complètement l'interface

    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
    unit Unit2;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Classes, Forms;
     
    const
      WM_MYPROGRESS_MESSAGE = WM_USER + 1;
     
    type
      TCalculsLongs = class(TThread)
      private
        procedure DoUpdateProgress(const ProgressValue: Integer);
      public
        FNotifyHandle: Hwnd;
        procedure Execute; override;
      end;
     
    implementation
     
    { TCalculsLongs }
     
    {======================================================================================================================}
     
    procedure TCalculsLongs.DoUpdateProgress(const ProgressValue: Integer);
    begin
      if FNotifyHandle <> 0 then begin
          SendMessage(FNotifyHandle, WM_MYPROGRESS_MESSAGE, ProgressValue, 0);
        // PostMessage(FNotifyHandle, WM_MYPROGRESS_MESSAGE, ProgressValue, 0);
      end;
    end;
     
    {======================================================================================================================}
     
    procedure TCalculsLongs.Execute;
    var
      i1, i2, i3, i4: Integer;
    begin
      inherited;
     
      for i1 := 0 to 100 do begin         // Calculs longs
        for i2 := 0 to 10000 do begin
          for i3 := 0 to 10000 do begin
            Inc(i4);
          end;
        end;
      DoUpdateProgress(i1);
      end;
    end;
     
    {======================================================================================================================}
     
    end.
    et dans ma fiche pricipale:

    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
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Classes, Controls, Forms, StdCtrls, ExtCtrls, ComCtrls, Unit2, ...;
     
    type
      TForm1 = class(TForm)    
        Button1: TButton;
        ProgressBar1: TProgressBar;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
        procedure MyThreadProgressEvent(var Msg: TMessage); message WM_MYPROGRESS_MESSAGE;
      public
        { Public declarations }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    var
      CalculsLongs: TCalculsLongs;
     
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      CalculsLongs := TCalculsLongs.Create(True);
      CalculsLongs.FNotifyHandle := Form1.Handle;
      try
        CalculsLongs.Execute;
      finally
        CalculsLongs.Free;
      end;
    end;
     
    {======================================================================================================================}
     
    procedure TForm1.MyThreadProgressEvent(var Msg: TMessage);
    begin
      ProgressBar1.Position := Msg.WParam;
    end;
     
    {======================================================================================================================}
     
    end.
    Je pensais que je pourrai au moins déplacer la fiche pendant que les calculs ont lieu mais tout reste figé tant que les calculs ne sont pas finis.

    Est-ce que vous pourriez me dire où je fais erreur ?
    Merci d'avance !

  2. #2
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    Je crois que tu n'as pas bien compris le fonctionnement du thread
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
      CalculsLongs := TCalculsLongs.Create(True);
      CalculsLongs.FNotifyHandle := Form1.Handle;
      try
        CalculsLongs.Execute;
      finally
        CalculsLongs.Free;
      end;
    Ceci n'a pas de sens, il ne faut pas appeler la fonction Execute du thread. D'ailleurs, celle-ci devrait être déclarée protected.
    Il faut plutôt faire ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    CalculsLongs := TCalculsLongs.Create(True);
    CalculsLongs.FNotifyHandle := Form1.Handle;
    CalculsLongs.FreeOnTerminate := True;
    CalculsLongs.Resume;
    Le Resume va démarrer le thread, mais rendre la main immédiatement.
    sjrd, ancien rédacteur/modérateur Delphi.
    Auteur de Scala.js, le compilateur de Scala vers JavaScript, et directeur technique du Scala Center à l'EPFL.
    Découvrez Mes tutoriels.

  3. #3
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 522
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 522
    Points : 25 052
    Points
    25 052
    Par défaut
    Ne pas appeler inherited dans Execute car la méthode de l'ancêtre est abstraite (cela déclenche une erreur)
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    707
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 707
    Points : 777
    Points
    777
    Par défaut
    Ca marche !

    1- en effet j'ai du mal avec le concept mais je commence à piger (dès que ça devient un peu abstrait, mon cerveau sature)...
    2- dans un premier temps j'avais utilisé "Resume" mais il ne se passait rien, c'est pour ça que j'étais passé à Execute qui au moins faisait quelque chose. Maintenant ça roule avec Resume donc j'avais sûrement oublié un élément important !
    3- pour le "inherited", c'est pas ma faute, c'est l'autocomplétion de code qui me l'a inséré

    Merci à tous deux, avec ça je vais enfin pouvoir avancer !

  5. #5
    Membre éclairé
    Profil pro
    Développeur Java
    Inscrit en
    Mars 2004
    Messages
    624
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Mars 2004
    Messages : 624
    Points : 681
    Points
    681
    Par défaut
    Il y aussi une très bonne doc sur le site : http://lberne.developpez.com/delphi/...us_threads.pdf

    Ca permet de bien comprendre le fonctionnement des threads

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [timer & thread] timeout & socket non bloquant
    Par untipy dans le forum Réseau
    Réponses: 33
    Dernier message: 22/08/2007, 08h37
  2. [Débutant] boost::thread non-lvalue
    Par Tymk dans le forum Boost
    Réponses: 16
    Dernier message: 18/11/2006, 14h23
  3. [débutant] thread et TMediaPlayer
    Par Tymk dans le forum C++Builder
    Réponses: 5
    Dernier message: 15/01/2005, 14h06
  4. Réponses: 3
    Dernier message: 16/03/2004, 16h42
  5. [API] Communication série NON-bloquante : OVERLAPPED/Thread
    Par Rodrigue dans le forum C++Builder
    Réponses: 2
    Dernier message: 07/11/2003, 13h43

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