Zitat von
Apollonius:
Zunächst einmal würde ich nur einen Threadpool instanziieren, nicht einen für jeden Socket.
Das tue ich auch nicht
Zitat von
Apollonius:
Dazu solltest du dann auch den Threadpool etwas verändern, sodass du nicht mehr ein OnWork-Ereignis hast, sondern einfach als Job einen Methodenzeiger übergibst (evtl. mit einem weitern Kontext-Parameter), der dann ausgeführt wird. Mit dem zusätzlichen Parameter nutzt du dann auch die 12 Byte voll aus.
In diesem einen OnWork Event werden alle Clientdaten bearbeitet.
Zitat von
Apollonius:
Zum zweiten würde ich für jeden ClientSocket ein Flag Queued einführen. Dieses setzt du auf True, wenn du ihn in die Warteschlange stellst, und am Ende der Abarbeitungsroutine wieder auf False. So vermeidest du, dass ein Socket mehrfach in die Warteschlange gesetzt wird.
Ja das hatte ich vor, nachdem ich gemerkt habe, dass ich ansonste Probleme bekomme. Habe es aber noch nicht eingebaut.
Zitat von
Apollonius:
Könntest du noch etwas genauer sagen, wo genau du die Daten abrufst und wie du auf neue Daten prüfst?
Kann dir Quellcode geben. Die ganzen Sockets sind noch alle in Entwicklung und einige Dinge sind nicht so Ideal evtl:
Delphi-Quellcode:
// Wird im Mainthread aufgerufen
procedure TServerSocket.Listen;
var id: Cardinal;
begin
FClosed := false;
FSocket.Open;
BeginThread(nil,0,@TServerSocket_CheckData,Self,0,id);
BeginThread(nil,0,@TServerSocket_Listen,Self,0,id);
end;
procedure TServerSocket_CheckData(Server: TServerSocket);
var i: Integer;
begin
with Server do
begin
while not FClosed do
begin
for i := FClients.Count-1 downto 0 do
if FClients[i].DataAvailable then
FThreadPool.AddJob(FClients[i]);
sleep(1);
end;
end;
end;
// Der Threadpool
procedure TThreadPool.AddJob(AJob: TObject);
begin
PostQueuedCompletionStatus(FIOComPort,SizeOf(TObject),Cardinal(AJob),nil);
end;
procedure TThreadPoolThread.GetJob;
var bytes: Cardinal;
over: POverlapped;
AJob: Cardinal;
begin
if GetQueuedCompletionStatus(FIOComPort,bytes,AJob,over,0) then
FJob := TObject(AJob)
else
FJob := nil;
end;
procedure TThreadPoolThread.Execute;
begin
while not FDead do
begin
GetJob;
if (Assigned(FOnWork)) and (Assigned(FJob)) then
FOnWork(Self,FJob);
sleep(1);
end;
end;
Sollte das nicht reichen, dann kann ich notfalls auch die 2 Units anhängen..
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."