AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi TThread mit WaitForMultipleObjects in DLL arbeitet nicht ?
Thema durchsuchen
Ansicht
Themen-Optionen

TThread mit WaitForMultipleObjects in DLL arbeitet nicht ?

Ein Thema von Rumpi · begonnen am 15. Nov 2003 · letzter Beitrag vom 9. Dez 2003
Antwort Antwort
Seite 1 von 2  1 2      
Rumpi

Registriert seit: 26. Aug 2003
Ort: Berlin
72 Beiträge
 
#1

TThread mit WaitForMultipleObjects in DLL arbeitet nicht ?

  Alt 15. Nov 2003, 19:21
Hallo,
Delphi-Quellcode:

unit cl_Thread;

interface
  uses Windows, Classes, syncobjs, Sysutils;

type

  TTimerThread = class(TThread)
  private
    { Private-Deklarationen }
    FEnabled : Boolean;
    FOneSec : Boolean;
    FOnNotify : TNotifyEvent;
    FInterval : Longint;
    FTag : Longint;
    FCloseEvent : TSimpleEvent;
    FEnableEvent : TSimpleEvent;
    FLastSec : Word;
  public
    constructor Create( OnNotify: TNotifyEvent ); overload;
    constructor Create( aInterval: Longint; OnNotify: TNotifyEvent ); overload;
    destructor Destroy; override;
    procedure Stop;
  protected
    procedure Execute; override;
    procedure Notify;
    procedure SetEnabled( Value: Boolean );
    procedure SetInterval( Value: Longint );
  published
    property Interval: Longint read FInterval write SetInterval;
    property Enabled : Boolean read FEnabled write SetEnabled;
    property Tag : Longint read FTag write FTag;
  end;

implementation

constructor TTimerThread.Create( OnNotify: TNotifyEvent );
begin
  inherited Create( True );
  FreeOnTerminate := True;
  FOnNotify := OnNotify;
  FInterval := 50;
  FCloseEvent := TSimpleEvent.Create;
  FEnableEvent := TSimpleEvent.Create;
  FEnabled := True;
  FOneSec := True;
  Resume;
end;

constructor TTimerThread.Create( aInterval: Longint; OnNotify: TNotifyEvent );
begin
  inherited Create( True );
  FreeOnTerminate := True;
  FOnNotify := OnNotify;
  FInterval := aInterval;
  FCloseEvent := TSimpleEvent.Create;
  FEnableEvent:= TSimpleEvent.Create;
  FEnabled := False;
  FOneSec := False;
  Resume;
end;

destructor TTimerThread.Destroy;
begin
  FCloseEvent.Free;
  Inherited Destroy;
end;

procedure TTimerThread.Execute;
var
  Signaled : Integer;
  h, m, s, ms : Word;
  EventHandles: array[0..1] of THandle;
begin
  EventHandles[0] := FCloseEvent.Handle;
  EventHandles[1] := FEnableEvent.Handle;
  repeat
    Signaled := WaitForMultipleObjects( 2, @EventHandles, False, FInterval );
    case Signaled of

      // Close event, terminate the thread
      WAIT_OBJECT_0 :
        begin
          ResetEvent(FCloseEvent.Handle);
          Break;
        end;

      WAIT_OBJECT_0 + 1:
        begin
          ResetEvent(FEnableEvent.Handle);
          FEnabled := True;
        end;

      //
      WAIT_TIMEOUT :
        if Not FOneSec then
          Synchronize(Notify)
        else
        begin
          // Has a second passed ?
          DecodeTime( Now, h, m, s, ms );
          if s <> FLastSec then
          begin
            //Notify;
            Synchronize(Notify);
            FLastSec := s;
          end;
        end;

    end;
  until Terminated;
end;

procedure TTimerThread.Notify;
begin
  if Assigned( FOnNotify ) and FEnabled then
    FOnNotify( Self );
end;

procedure TTimerThread.Stop;
begin
  FEnabled := False;
  SetEvent(FCloseEvent.Handle);
end;

procedure TTimerThread.SetEnabled( Value: Boolean );
begin
  if FEnabled <> Value then
    if Value then
      SetEvent(FEnableEvent.Handle)
    else
      FEnabled := False;
end;

procedure TTimerThread.SetInterval( Value: Longint );
begin
  if FEnabled then
  begin
    FEnabled := False;
    FInterval := Value;
    SetEvent(FEnableEvent.Handle);
  end
  else
    FInterval := Value;
end;


end.

TTimerThread funtioniert solange man ihn aus einer Application startet,
aber nicht in einer DLL ... Warum ?

Bleibt bei WaitForMultipleObjects stehen obwohl ein Interval gesetzt ist !

Ich musste also wieder zu TTimer greifen, aber ich würde gerne
TTimerThread auch in DLL's verwenden wollen.

Kann mir das mal einer erklären

mfg Rumpi
  Mit Zitat antworten Zitat
Rumpi

Registriert seit: 26. Aug 2003
Ort: Berlin
72 Beiträge
 
#2

Re: TThread mit WaitForMultipleObjects in DLL arbeitet nicht

  Alt 15. Nov 2003, 21:51
Kann mir keiner Helfen ?

mfg Rumpi

[edit=Daniel B]Doppelpost gelöscht. Mfg, Daniel B[/edit]
[edit=Daniel B]BB-Code wieder eingeschaltet. Mfg, Daniel B[/edit]
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.116 Beiträge
 
Delphi 11 Alexandria
 
#3

Re: TThread mit WaitForMultipleObjects in DLL arbeitet nicht

  Alt 15. Nov 2003, 21:59
Moin Rumpi,



findest Du es nicht auch reichlich übertrieben, nach 2,5 Stunden Deinen Thread zu pushen?
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
Rumpi

Registriert seit: 26. Aug 2003
Ort: Berlin
72 Beiträge
 
#4

Re: TThread mit WaitForMultipleObjects in DLL arbeitet nicht

  Alt 15. Nov 2003, 22:10
So war das nicht gemeint.
Das ist nur eine Frage und kein Pushen.

mfg Rumpi
  Mit Zitat antworten Zitat
Benutzerbild von Sharky
Sharky

Registriert seit: 29. Mai 2002
Ort: Frankfurt
8.252 Beiträge
 
Delphi 2006 Professional
 
#5

Re: TThread mit WaitForMultipleObjects in DLL arbeitet nicht

  Alt 15. Nov 2003, 22:13
Hai Rumpi,

ich bin mir sicher das jemand antwortet wenn er die Antwort kennt.

Pushen (ob mit absicht oder nicht) innerhalb von weniger als 24h ist halt nicht die feine Art.
Stephan B.
"Lasst den Gänsen ihre Füßchen"
  Mit Zitat antworten Zitat
Bernd Ua

Registriert seit: 10. Nov 2003
Ort: Lindhorst
87 Beiträge
 
Delphi 11 Alexandria
 
#6

Re: TThread mit WaitForMultipleObjects in DLL arbeitet nicht

  Alt 15. Nov 2003, 23:17
Hi ungeduldiger,

so ausm Bauch - schau dir mal an, ob in der DLL die Varaible IsMultiThread auf true gesetzt
ist oder nicht und setze sie ansonsten auf true.

Dein Timer ist übrigens ein toller Plan - denk aber daran, dass das reale Intervall
gleich "eingestelltes Intervall + Ausführungszeit Eventhandler" ist, da Dein Synchronize
den Thread anhält

Bernd
Bernd Ua
  Mit Zitat antworten Zitat
Rumpi

Registriert seit: 26. Aug 2003
Ort: Berlin
72 Beiträge
 
#7

Re: TThread mit WaitForMultipleObjects in DLL arbeitet nicht

  Alt 15. Nov 2003, 23:49
Vielen Danke Bernd für den Input,

Ich habe die Variable auf True gesetzt aber es tut sich nix.
Es ist echt komisch, alle anderen Threads mit WaitForMultipleObjects
ohne einen TimeOut gehen ja ( Lesen einer RS232 EventFlags ).

Ich versuche Timer so gut es geht zu meiden.

Danke für deinen Hinweis mit Synchonize( X ),
bei meinen Funktionen ist das genau so gewollt,
der TimerThread soll erst danch wieder den Intervall starten.

mfg Rumpi
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#8

Re: TThread mit WaitForMultipleObjects in DLL arbeitet nicht

  Alt 16. Nov 2003, 04:47
Zitat von Bernd Ua:
so ausm Bauch - schau dir mal an, ob in der DLL die Varaible IsMultiThread auf true gesetzt
ist oder nicht und setze sie ansonsten auf true.
Sollte eigentlich überflüssig sein, da er die VCL Thread-Klasse benutzt. Beim erzeugen des Threads wir die Variable automatisch auf True gesetzt. Man muss es nur von Hand machen, wenn man die API Funktion CreateThread ohne den Delphi Wrapper BeginThread benutzt.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Bernd Ua

Registriert seit: 10. Nov 2003
Ort: Lindhorst
87 Beiträge
 
Delphi 11 Alexandria
 
#9

Re: TThread mit WaitForMultipleObjects in DLL arbeitet nicht

  Alt 16. Nov 2003, 10:39
Moin Rumpi,

jetzt bin ich ein bisschen wacher

Eigentlich sollte nix dagegen sprechen, dass WaitForMultipleObjects auch in DLLs
funktioniert. Interessehalber habe ich deinen Thread mal in ein Projekt kopiert und
aus ner DLL laufen lassen. Da hängt sich nix auf und bleibt nix stehen.

Das dumme ist, dass in Deinem Profil und der frage nix zur Delphi Version steht
(... und dass ich normalerweise Synchronize meide <g>).

Die Implementierung von Synchronize hat sich zwischen D5 und D6 geändert ( wg Crossplatform).

Fall D5 oder kleiner :
Bei D5 stellt Synchronize eine Nachricht mit einem Pointer auf den Thread in die
Nachrichtenschleife der Applikation (CM_EXECPROC) die zu einem Deadlock führt,
wenn die Applikation im Haupthread gerade auf irgendwas mit WaitForMultipleObjects wartet
( einer der Gründe warum ich Synchronize meide )
Ersetze dann mal spasseshalber Dein WaitForMultipleObjects durch MsgWaitForMultipleObjects !

Fall D6 oder höher
Synchronize erzeugt ein Event und stellt das Event in eine globale Variable namens SyncList ein (Unit Classes)
die bei GUI Applikationen automatisch ansonsten manuell über CheckSynchronize geprüft werden kann.
Hier haben DLL und EXE zweimal die globale Variable SyncList, dummerweise bleibt die Synclist der Exe immer leer
und Dein Event wird nie gerufen.
Workaround hier: Aktiviere bei EXE und DLL Runtimepackages ( rtl sollte reichen)

Grüsse Bernd

@Luckie: war nicht mehr richtig wach gestern
Bernd Ua
  Mit Zitat antworten Zitat
Rumpi

Registriert seit: 26. Aug 2003
Ort: Berlin
72 Beiträge
 
#10

Re: TThread mit WaitForMultipleObjects in DLL arbeitet nicht

  Alt 16. Nov 2003, 12:54
Hi Bernd,

... vorab schon mal Danke

Zitat von Bernd Ua:
Das dumme ist, dass in Deinem Profil und der frage nix zur Delphi Version steht
(... und dass ich normalerweise Synchronize meide <g>).
Ich verwende D6 und D7 ( manchmal auch noch D4 oder D1 ) sorry werde ich das nächste Mal angeben.

Zitat von Bernd Ua:
Synchronize erzeugt ein Event und stellt das Event in eine globale Variable namens SyncList ein (Unit Classes)
die bei GUI Applikationen automatisch ansonsten manuell über CheckSynchronize geprüft werden kann.
Hier haben DLL und EXE zweimal die globale Variable SyncList, dummerweise bleibt die Synclist der Exe immer leer
und Dein Event wird nie gerufen.
Workaround hier: Aktiviere bei EXE und DLL Runtimepackages ( rtl sollte reichen)
Ich habe nur im TimerThread Synchronize weggelassen und schon gings
Delphi-Quellcode:
  // Synchronize( Notify ); // so gehts nur wenn in einer EXE
  Notify; // und schon gehts auch in der DLL
                             // hatte ich ja schon als Alternative im code
Ich musste "nicht" in der EXE und oder der DLL Runtimepackages aktivieren

Danke noch einmal Bernd.

mfg Rumpi
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:44 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz