![]() |
QueueUserWorkItem wie sieht es in Delphi aus?
Die Funktion ist so deklariert:
Code:
Mit welchem Datentyp übersetzt man den ersten Parameter in Delphi?
BOOL QueueUserWorkItem(
LPTHREAD_START_ROUTINE Function, PVOID Context, ULONG Flags ); Im PSDK steht noch dazu: Zitat:
|
Re: QueueUserWorkItem wie sieht es in Delphi aus?
OK, ich habs jetzt. Mein Beispielprogramm sieht jetzt so aus:
Delphi-Quellcode:
Allerdings habe ich da noch ein Verständnisproblem oder so:
type
TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } i: Cardinal; public { Public declarations } end; type TThreadParams = record ThreadID: Cardinal; end; PThreadParams = ^TThreadParams; var Form1 : TForm1; function QueueUserWorkItem(LPTHREAD_START_ROUTINE: Pointer; Context: Pointer; Flags: DWORD): DWORD; stdcall; external 'kernel32.dll'; const WT_EXECUTEDEFAULT = $00000000; WT_EXECUTEINIOTHREAD = $00000001; WT_EXECUTEINUITHREAD = $00000002; WT_EXECUTEINWAITTHREAD = $00000004; WT_EXECUTEONLYONCE = $00000008; WT_EXECUTEINTIMERTHREAD = $00000020; WT_EXECUTELONGFUNCTION = $00000010; WT_EXECUTEINPERSISTENTIOTHREAD = $00000040; WT_EXECUTEINPERSISTENTTHREAD = $00000080; WT_TRANSFER_IMPERSONATION = $00000100; implementation {$R *.dfm} function Thread(p: Pointer): Integer; var hWnd: THandle; ThreadID: Cardinal; begin ThreadID := PThreadParams(p)^.ThreadID; Messagebox(0, PChar(IntToStr(ThreadID)), '', 0); Dispose(p); result := 0; end; procedure TForm1.Button1Click(Sender: TObject); var ThreadParams: PThreadParams; begin New(ThreadParams); ThreadParams.ThreadID := i; if QueueUserWorkItem(@Thread, ThreadParams, WT_EXECUTEONLYONCE) = 0 then ShowMessage(SysErrorMessage(GetLastError)); Inc(i); end; Ich klicke einmal, ich bomme die Messagebox null, ich klicke ein zweites mal, ich bekomme die Messagebox eins, ich klicke ein drittes mal, es passiert nichts, ich klicke ein viertes mal, es passiert nichts, ich klicke ein fünftes mal, ich bekomme die Messagebox drei. Entsprechd wird auch nur die Anzahl der Threads im Taskmanager erhöht. Aber sollte es nicht so sein, dass bei jedem Aufruf von QueueUserWorkItem ein Thread erzeugt wird? Oder wie soll das funktionieren? |
Re: QueueUserWorkItem wie sieht es in Delphi aus?
Zitat:
|
Re: QueueUserWorkItem wie sieht es in Delphi aus?
Ein einfacher Pointer tut es auch, wie man sieht. ;) Aber ich hätte jetzt gerne noch Aufklärung über das Funktionsprinzip. :gruebel:
|
Re: QueueUserWorkItem wie sieht es in Delphi aus?
die Calling-Convention deiner Thread-Funktion stimmt übrigens nicht; richtig wäre StdCall:
Delphi-Quellcode:
function Thread(p: Pointer): Integer; StdCall;
|
Re: QueueUserWorkItem wie sieht es in Delphi aus?
WT_EXECUTEONLYONCE steht bei MS nicht in der Liste der für QueueUserWorkItem gültigen Flags...
|
Re: QueueUserWorkItem wie sieht es in Delphi aus?
@Basilikum: Das ändert nichts am Verhalten.
@Union: Ist aber in WinNT.h deklariert. Aha, so gehts:
Delphi-Quellcode:
stdcall und WT_EXECUTELONGFUNCTION zusammen erzeugen jedes mal einen neuen Thread.
function Thread(p: Pointer): Integer; stdcall;
var ThreadID: Cardinal; begin ThreadID := PThreadParams(p)^.ThreadID; Messagebox(0, PChar(IntToStr(ThreadID)), '', 0); Dispose(p); result := 0; end; procedure TForm1.Button1Click(Sender: TObject); var ThreadParams: PThreadParams; begin New(ThreadParams); ThreadParams.ThreadID := i; if QueueUserWorkItem(@Thread, ThreadParams, WT_EXECUTELONGFUNCTION) = 0 then ShowMessage(SysErrorMessage(GetLastError)); Inc(i); end; Aber hilft mir das bei folgendem Szenario: Ich habe einen Server zum dem verbinden sich Clients. Es sollen maximal fünf Client-Threads laufen. das heißt, wenn fünf Thread schon existieren, soll es keinen neuen mehr geben, sondern der sechste Cliuent soll sich erst verbinden können, wenn einer der ersten fünf Clients sich wieder verabschiedet hat. Wenn sich das mit QueueUserWorkItem machen läßt, wie löst man das problem am besten? Laut PSDK soll das ja möglcih sein: Zitat:
|
Re: QueueUserWorkItem wie sieht es in Delphi aus?
Zitat:
|
Re: QueueUserWorkItem wie sieht es in Delphi aus?
Ich weiß, ich spame, aber ich habe es gerade gefunden:
Delphi-Quellcode:
Übergibt man als Flag: WT_EXECUTEDEFAULT ergibt sich obige Situation: Dass Messagebox zwei nicht erscheint. Schließe ich eine alte Messagebox, erscheint Mesaagebox zwei, ohne dass ich noch mal auf die Schaltfläche geklickt habe. Tut also alles, wie es soll. ;)
procedure TForm1.Button1Click(Sender: TObject);
var ThreadParams: PThreadParams; begin New(ThreadParams); ThreadParams.ThreadID := i; if QueueUserWorkItem(@Thread, ThreadParams, WT_EXECUTEDEFAULT) = 0 then ShowMessage(SysErrorMessage(GetLastError)); Inc(i); end; Fällt jemanden jetzt dazu eine schöne Demoanwendung ein? |
Re: QueueUserWorkItem wie sieht es in Delphi aus?
Zitat:
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:19 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz