Results 1 to 7 of 7

Thread: Event vanuit een Thread

  1. #1

    Event vanuit een Thread

    Goedemorgen beste programmeurs,

    Ik heb eigenlijk een korte vraag over een EVENT aanroepen vanuit een Thread.
    Deze wordt verder afgehandeld in de Main Thread.

    Hier twee opties welke het beste is vanuit mijn Thread.

    Code:
    Type
      TStartStopEvent = procedure(Sender: TObject; Index: Integer; ControlType: TStartStopControl) of object;
    Code:
    class procedure TAutoStart22.DoStartStopEvent(Sender: TObject; Index: Integer; ControlType: TStartStopControl);
    begin
      if Assigned(FStartStopEvent) then
        FStartStopEvent(Sender, Index, ControlType);
    end;
    OF...

    Code:
    class procedure TAutoStart22.DoStartStopEvent(Sender: TObject; Index: Integer; ControlType: TStartStopControl);
    begin 
      TThread.Synchronize(TThread.Current, procedure
      begin
        if Assigned(FStartStopEvent) then
          FStartStopEvent(Sender, Index, ControlType);
      end);
    end;
    Ik heb geleerd dat je vanuit een Thread altijd naar de Main Thread dit moet doen via een Synchronize.
    Het kan zijn dat het hier net iets anders mag?

    Kunt u mij advies geven of weet u de juiste oplossing?

    Alvast bedankt voor het meedenken.

    Groetjes,
    Eduard.

  2. #2
    In het eerste geval wordt FStartStopEvent aangeroepen vanuit de TAutoStart22 thread. Dat is op zich niet erg, maar betekent dat je in de event handler geen VCL componenten mag aanspreken, bijvoorbeeld, omdat die niet thread safe zijn, en daardoor in een foutieve staat kunnen komen, wat erg vreemde en lastig te debuggen effecten kan geven.

    Synchronize zorgt ervoor dat die code juist in de main thread draait, dus dat lost dat probleem op, maar het zorgt er eigenlijk wel voor dat je thread gepauzeerd wordt, terwijl je main thread het event afhandelt, dus dat heeft weer nadelige effecten op de performance, afhankelijk van hoeveel tijd de eventhandler gebruikt t.o.v. de rest van de thread.
    Als je zeker weet dat de event handler in de main thread moet draaien, dan is Synchronize de makkelijkste optie, en zou ik de tweede methode kiezen.

    Als je een generiek thread object maakt (voor een library o.i.d.) waarvoor dat niet zo zeker is, dan kan je ook gewoon de event handler aanroepen op de eerste manier. De event handler zelf kan dan alsnog TThread.Synchronize gebruiken om (een deel van) z'n logica gesynchronized uit te voeren.

    En er zijn nog andere oplossingen. Je kan bijvoorbeeld PostMessage gebruiken om messages te sturen naar een handle (bijvoorbeeld die van het main form). Aan de message kan je twee ints meegeven voor kleine beetjes informatie. Die ints kunnen met een trucje ook andere waardes bevatten. Als TStartStopControl een enum is oid, dan kan je die typecasten naar int. Een dergelijke message kan vaak prima zijn voor een voortgangsindicator o.i.d.
    Die ints kunnen ook pointers zijn, al moet je er dan weer wel voor zorgen dat die pointers wijzen naar iets dat wél netjes opgeruimd wordt, maar niet te vroeg en niet te vaak.

    Lang verhaal kort:
    - Als dit verhaal wazig is: Optie 2
    - Als de event handler in een form zit: Optie 2
    - Als je wat voor VCL class dan ook gebruikt in de event handler: Optie 2
    Last edited by GolezTrol; 19-Dec-22 at 17:38.
    1+1=b

  3. #3
    Het is mij nu geheel duidelijk. De PostMessage manier lijkt mij wel wat.
    Bedankt GolezTrol :-)

  4. #4
    Een klein nadeeltje daarvan, wat ik misschien had moeten vertellen, is dat een form handle kan veranderen, als het onderliggende Windows-venster opnieuw gecreate moet worden.

    Dit gebeurt bijvoorbeeld in ieder geval als je de border style van een scherm aanpast, maar wellicht ook op andere momenten. Misschien geen probleem, maar als het ontvangen van de berichten-stroom ineens lijkt te stoppen, dan zou dat de oorzaak kunnen zijn.
    1+1=b

  5. #5
    Ik heb die PostMessage gewoon werkend en sluiten en openen etc blijft de notify gewoon lopen. Gebruik trouwens een stuk of 30 PostMessage in mijn programma. Geen probleem. Dat is via de BASS codec.
    Is trouwens gewoon een create form bij de DPR. Dus geen dynamische Create, Destroy scherm.
    Ik heb nu wel gekozen voor optie 2 want dat maakt in snelheid notify geen verschil. Thread mag wat minder snel. Geen probleem.
    Bedankt voor je bijdrage en informatie :-)
    Groetjes.

  6. #6
    De actie op een threasafe queue plaatsen is ook een optie.

  7. #7
    Ik zie het Miep maar het is maar een labeltje dus dat kan wel denk ik zo

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •