Autor |
Beitrag |
Heiko
      
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: Mo 25.12.06 20:05
Hallo Leuts,
inzwischen habe ich mich daran gewöhnt mit Threads zu arbeiten, da dadurch die GUI noch weiterhin flüssig reagiert, obwohl es noch genug zu tun gibt  . Leider haben Threads den Nachteil, dass sie immer das maximum an Ressourcen verbrauchen, außer wenn man den mit sleep oder GetMessage abbremst. Da ja mein Thread auch mit dem Rest kummunizieren soll, habe ich mit für GetMessage entschieden, da ich dort auch keine Synchronisation zur Kommunikation brauche.
ICh stehe jetzt aber vor dem Problem das Thread-Handle zu bekommen, was ja BeginThread zurückgibt, aber leider nicht dem Thread selber mitteilt. Weiß einer von euch wie man aus dem Thread heraus ohne Synchronisation an das Thread-Handle kommt?
Grüße Heiko
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Mo 25.12.06 20:11
GetCurrentThread 
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Heiko 
      
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: Di 26.12.06 10:57
Habe ich auch schon probiert, aber da bekomme ich den maximalen Cardinal zurück, stimmt also nicht  .
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Di 26.12.06 11:28
Sollte aber nicht der Fall sein:
Zitat: | GetCurrentThread
Retrieves a pseudo handle for the calling thread. |
|
|
Heiko 
      
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: Di 26.12.06 12:08
Luckie hat folgendes geschrieben: | Sollte aber nicht der Fall sein:
Zitat: | GetCurrentThread
Retrieves a pseudo handle for the calling thread. |
|
Das hatte ich bei MSDN auch gelesen, aber trotzdem bekomme ich nonsense zurück  .
Mein Code:
Delphi-Quelltext 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:
| procedure TestThread(var ThreadID: Cardinal); var Thread: Integer; msg: tagMSG; begin Thread:=GetCurrentThread; while GetMessage(msg, Thread, 0, 0) do begin if msg.message = WM_CREATE then begin Form1.Caption:='sdf'; end; end; CloseHandle(Thread); end;
procedure TForm1.FormCreate(Sender: TObject); var ThreadID: Cardinal; Thread: Integer; begin Thread:=BeginThread(nil, 0, @TestThread, @ThreadID, 0, ThreadID); ShowMessage(IntToStr(Thread)); SendMessage(Thread, WM_CREATE, 0, 0); end; |
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Di 26.12.06 13:58
Kannst Du mal kurz sagen, was GetLastError meldet? Bitte vor dem GetCurrentThread-Aufruf mit SetLastError auf 0 setzen, da die VCL häufig genug auch Fehlercodes ignoriert ...
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Heiko 
      
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: So 28.12.08 21:56
Um den Thread wieder auszugraben: GetLastError liefert 0 zurück und der Wert ist nicht MaxCardinal sondern -2 als Cardinal dargestellt.
Ich frage mich gerade nur: soll "pseudo handle" heißen, dass es nicht zum empfangen von Nachrichten geeignet ist, oder wie soll man es interpretieren?
Oder wie würdet ihr Messages im Thread empfangen?
|
|
jaenicke
      
Beiträge: 19312
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 28.12.08 22:19
Ich würde einfach TThread benutzen.
Dort kannst du z.B. die WndProc überschreiben. Und das Handle hast du auch direkt.
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: So 28.12.08 22:23
GetCurrentThreadId vielleicht? Ob das dem entspricht, was du suchst, weiss ich jetzt nicht. Ist jedenfalls eine systemweit eindeutige Id.
|
|
Heiko 
      
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: So 28.12.08 22:25
delfiphan hat folgendes geschrieben : | GetCurrentThreadId vielleicht? Ob das dem Handle entspricht weiss ich nicht. Ist jedenfalls eine systemweit eindeutige Id. |
Leider nein. Die Werte sind verschieden, die da herauskommen.
@TThread: Mal schauen, wie die das gemacht haben.
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: So 28.12.08 22:48
Versuch mal THandle als Datentyp zu nehmen. Das ist ein Cardinal in Delphi.
C#-Quelltext 1:
| HANDLE WINAPI GetCurrentThread(void); |
Und was ein Pseudohandle ist, wird in der Hilfe auch erklärt:
Zitat: | A pseudo handle is a special constant that is interpreted as the current thread handle. The calling thread can use this handle to specify itself whenever a thread handle is required. |
Moderiert von Narses: C in CS-Tag gewandelt
|
|
Heiko 
      
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: So 28.12.08 22:59
Luckie hat folgendes geschrieben : | Versuch mal THandle als Datentyp zu nehmen. Das ist ein Cardinal in Delphi.
[c]HANDLE WINAPI GetCurrentThread(void);[/c] |
THandle ist auch nur ein Cardinal, von daher ist es wurscht, solange 32Bit 32Bit sind  .
Luckie hat folgendes geschrieben : | Und was ein Pseudohandle ist, wird in der Hilfe auch erklärt: |
Äh ja: ich verstehe es so, dass es damals selber an sich arbeiten kann (komischer Ausdruck, ich weiß  ) - aber es klingt für mich so, als ob es ein anderes Handle sein könnte als das, worüber es von außen zu erreichen ist.
|
|
Heiko 
      
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: Di 30.12.08 00:00
ICh habe mir jetzt mal TThread genauer angeschaut, also wie die es dort geregelt haben. Die übergeben einfach beim erzeugen die eigene Klasse und kommen so an das Handle ran.
Nun ich habe es ebenso gemacht, allerdings empfängt er nix auf dem Handle. Habe ich einen Fehler drin oder ist das Handle einfach nicht dafür geeignet?
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:
| unit DanSo;
interface
uses Windows,
DanSo_Messages,
fmod;
type TDanSoPlayer = class(TObject) private FHandle: THandle; public constructor Create; procedure WndProc; destructor Destroy; override; end;
implementation
function DanSoPlayerThread(DanSoPlayer: TDanSoPlayer): Integer; begin DanSoPlayer.WndProc; Result:=0; end;
constructor TDanSoPlayer.Create; var ThreadID: Cardinal; begin FHandle:=BeginThread(nil, 0, @DanSoPlayerThread, Pointer(Self), 0, ThreadID); end;
destructor TDanSoPlayer.Destroy; begin SendMessage(FHandle, WM_DanSo_Destroy, 0, 0); WaitForSingleObject(FHandle, INFINITE); if FHandle <> 0 then CloseHandle(FHandle); end;
procedure TDanSoPlayer.WndProc; var msg: tagMSG; begin while GetMessageW(msg, FHandle, 0, 0) do begin case msg.message of WM_DanSo_Destroy: begin break; end; end; TranslateMessage(msg); DispatchMessageW(msg); end; end;
end. |
@Luckie: THandle=Cardinal - ich hab nochmal nachgeschaut 
|
|
|