E 'difficile per me dire di non usare Sleep
da quando io lo uso per tutto il tempo, ma Application.ProcessMessages
è in realtà una soluzione pericolosa, specialmente se usata in un ciclo. Non sono sicuro di quali informazioni stai visualizzando (poiché non riconosco la lingua) ma sembra che tu stia facendo alcune conversioni da Float a String. Sebbene queste conversioni vengano eseguite in una frazione di secondo, aggiungerle tutte insieme e potresti ottenere una lunga operazione. Supponiamo che tu decida di aggiungere un altro valore da aggiornare, che richiede alcuni calcoli (come i byte al secondo in un trasferimento di file). Questa conversione aggiungerà un po 'più di tempo a questa operazione, e prima che tu te ne accorga, potresti finire con un aggiornamento dell'interfaccia utente che impiega mezzo secondo (il che non sembra lungo, ma quando si parla di utilizzo del processore, questo è abbastanza un carico).
Pertanto, suggerirei di utilizzare una discussione per eseguire tutte queste conversioni, calcoli, ecc. E attivare gli eventi in base alle esigenze ogni volta che le informazioni sono cambiate. Ora un thread sarà sicuramente un po 'più complesso delle altre soluzioni proposte qui, senza dubbio. Ma usare un thread può significare anche una grande quantità di benefici. Tutto il tuo lavoro pesante può essere fatto in background mentre la tua applicazione risponde ancora perfettamente. Tieni presente che l'utilizzo di un thread può essere molto complicato, in particolare quando si tratta di aggiornamenti dell'interfaccia utente.
Ci sono alcuni modi per rendere un filo, ma cercherò di fare questa semplice ...
type
TMyThread = class;
TMyThreadEvent = procedure(Sender: TObject; const Val1, Val2: String) of object;
TMyThread = class(TThread)
private
FValue1: Integer;
FValue2: Integer;
FString1: String;
FString2: String;
FOnChange: TMyThreadEvent;
procedure SYNC_OnChange;
protected
procedure Execute; override;
public
constructor Create;
property Value1: Integer read FValue1 write FValue1;
property Value2: Integer read FValue2 write FValue1;
property String1: String read FString1;
property String2: String read FString2;
property OnChange: TMyThreadEvent read FOnChange write FOnChange;
end;
...
constructor TMyThread.Create;
begin
inherited Create(False);
FValue1 := '0';
FValue2 := '0';
end;
procedure TMyThread.Execute;
var
S1, S2: String;
DoChange: Bool;
begin
DoChange:= False;
FValue2:= DoSomeBigCalculation(FValue1); //Some random big calculation
S1:= FormatFloat('#,##0.#', FValue1);
S2:= FormatFloat('#,##0.#', FValue2);
if (S1 <> FString1) then begin
FString1:= S1;
DoChange:= True;
end;
if (S2 <> FString2) then begin
FString2:= S2;
DoChange:= True;
end;
if DoChange then
Synchronize(SYNC_OnChange);
end;
procedure TMyThread.SYNC_OnChange;
begin
if assigned(FOnChange) then
FOnChange(Self, FString1, FString2);
end;
Ora per utilizzare questo, è necessario impostare le proprietà Integer
come necessario. Assicurati di impostare l'evento OnChange
su una procedura con i parametri del tipo TMyThreadEvent
precedente. Ogni volta che un valore differisce dal suo valore originale (o vecchio), attiverà questo evento. Raccomando inoltre vivamente che qualsiasi codice di elaborazione che si possa avere e che produca questi valori sia messo al primo posto all'interno di un thread. Le possibilità di multi-threading sono enormi e si rivelano un grande vantaggio per le applicazioni che hanno molto successo in esse.
Si prega di notare che il mio codice sopra è solo un esempio digitato direttamente in questo sito Web, e non è testato. È solo per darti un'idea di come implementare un thread per fare il tuo aggiornamento.
Vivo secondo questa massima: "Se senti il bisogno di usare Sleep(), stai sbagliando". –
@nick Effettivamente. Il mio equivalente è "Non ci sono problemi per i quali il sonno è la soluzione". –
@NickHodges ecc. In che modo, quindi, soddisfi il requisito di una pausa quando vari livelli in profondità su una pila di thread? Lasciami indovinare: 'spendi anni a ri-implementare le specifiche proceduralmente scritte come macchine di stato, solo per poter usare un timer al posto di sleep() chiama'. Non c'è dubbio che i loop di A.P + sleep() nei gestori di GUI sono un abuso particolarmente debole, ma l'argomento 'sleep può essere usato male, quindi non usarlo affatto' è err .. 'difficile da supportare'. –