Delphi (XE2) Indy (10) Multithread Ping

J'ai une chambre avec 60 ordinateurs/périphériques (40 ordinateurs et 20 oscilloscopes Windows CE) et je voudrais savoir qui et tout le monde est en vie à l'aide de la commande ping. J'ai d'abord écrit un ping standard (voir ici Delphi Indy Ping Erreur 10040), qui fonctionne bien maintenant, mais prend une éternité quand la plupart des ordinateurs sont en mode hors connexion.

Donc ce que je suis en train de faire est d'écrire un MultiThread Ping mais je suis tout à fait de la difficulté avec elle. Je n'ai vu que très peu d'exemples sur internet et personne n'a été correspondre à mes besoins, c'est pourquoi j'ai essayer de l'écrire moi-même.

- Je utiliser XE2 et Indy 10 et le formulaire est uniquement constitué d'un mémo et un bouton.

unit Main;
interface
uses
Winapi.Windows, System.SysUtils, System.Classes, Vcl.Forms,
IdIcmpClient, IdGlobal, Vcl.StdCtrls, Vcl.Controls;
type
TMainForm = class(TForm)
Memo1: TMemo;
ButtonStartPing: TButton;
procedure ButtonStartPingClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
TMyPingThread = class(TThread)
private
fIndex : integer;
fIdIcmpClient: TIdIcmpClient;
procedure doOnPingReply;
protected
procedure Execute; override;
public
constructor Create(index: integer);
end;
var
MainForm: TMainForm;
ThreadCOunt : integer;
implementation
{$R *.dfm}
constructor TMyPingThread.Create(index: integer);
begin
inherited Create(false);
fIndex := index;
fIdIcmpClient := TIdIcmpClient.Create(nil);
fIdIcmpClient.ReceiveTimeout := 200;
fIdIcmpClient.PacketSize := 24;
fIdIcmpClient.Protocol := 1;
fIdIcmpClient.IPVersion := Id_IPv4;
//first computer is at adresse 211
fIdIcmpClient.Host := '128.178.26.'+inttostr(211+index-1);
self.FreeOnTerminate := true;
end;
procedure TMyPingThread.doOnPingReply;
begin
MainForm.Memo1.lines.add(inttostr(findex)+' '+fIdIcmpClient.ReplyStatus.Msg);
dec(ThreadCount);
if ThreadCount = 0 then
MainForm.Memo1.lines.add('--- End ---');
end;
procedure TMyPingThread.Execute;
begin
inherited;
try
fIdIcmpClient.Ping('',findex);
except
end;
while not Terminated do
begin
if fIdIcmpClient.ReplyStatus.SequenceId = findex then Terminate;
end;
Synchronize(doOnPingReply);
fIdIcmpClient.Free;
end;
procedure TMainForm.ButtonStartPingClick(Sender: TObject);
var
i: integer;
myPing : TMyPingThread;
begin
Memo1.Lines.Clear;
ThreadCount := 0;
for i := 1 to 40 do
begin
inc(ThreadCount);
myPing := TMyPingThread.Create(i);
//sleep(10);
end;
end;
end.

Mon problème est qu'il "semble" fonctionner lorsque je décommentez la "sleep(10)", et "semble" ne pas travailler sans elle. Cela pour vous dire que je suis manque un point dans le thread que j'ai écrit.

En d'autres termes. Quand le Sommeil(10) est dans le code. Chaque fois que j'ai cliqué sur le bouton pour obtenir de vérifier les connexions, le résultat était correct.

Sans sommeil(10), c'est le travail "en plus" de temps en temps, mais, à certains moments, le résultat est mauvais, me donnant un écho ping sur les ordinateurs hors-ligne et aucun écho ping sur ordinateur en ligne, est la réponse ping n'a pas été attribué pour le bon thread.

Tout commentaire ou aide est la bienvenue.

----- EDIT /IMPORTANT -----

Général suivi de cette question, @Darian Miller a commencé un Google Code du projet ici https://code.google.com/p/delphi-stackoverflow/ qui est une base de travail. Je marque sa réponse comme "accepté de répondre" mais les utilisateurs doivent se référer à ce projet open source (tout le crédit appartient à lui) car il va sûrement être étendu et mis à jour dans le futur.

source d'informationauteur HpTerm