Sto provando a eseguire una funzione o una procedura in Delphi in modo asincrono, ma senza utilizzare un componente, c'è un modo per farlo con le funzioni del delta core?Come chiamare una funzione/procedura in modo asincrono in Delphi (Senza componenti)
risposta
Si consiglia inoltre di eseguire la procedura su un thread. Utilizzare quindi l'evento OnTerminate per ottenere il risultato. Sì, in questi giorni di .NET e C# siamo in qualche modo rovinati dalla forma facile e conveniente di eseguire i metodi in modo asincrono, ma questo è il modo in cui funziona su Delphi.
Se si sta chiedendo se il VCL ha qualcosa di like BeginInvoke in .NET pronto per l'uso, la risposta è no. Tuttavia, è possibile ottenere qualcosa di abbastanza simile sotto forma di una piccola unità che si collega al programma, la libreria AsyncCalls di Andreas Hausladen. Non è un componente, quindi credo che si qualifica. Supporta anche Delphi dalla versione 5 in poi. Molto consigliato
Edit:
io aggiungo un esempio in quanto non hai in esecuzione. Se si ottiene il blocco del codice chiamante, il problema è che non viene mantenuto alcun riferimento al puntatore all'interfaccia IAsyncCall
restituito dalla funzione. L'oggetto che implementa l'interfaccia verrà quindi distrutto immediatamente quando il riferimento temporaneo non rientra nell'ambito. Il distruttore verrà chiamato nel contesto del thread VCL e chiamerà WaitForSingleObject()
o una funzione simile per attendere il completamento del thread worker. Il risultato è che il tuo thread VCL blocca.
otterrete il comportamento corretto se si mantiene un riferimento al puntatore di interfaccia:
type
TForm1 = class(TForm)
Button1: TButton;
Timer1: TTimer;
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure Button1Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
fAsyncCall: IAsyncCall;
procedure WaitForIt(ADelay: integer);
end;
Impostare il timer essere disabilitato e lasciare che hanno un tempo molto breve Interval
, dicono 50 ms. Il clic del pulsante avvia l'operazione asincrona:
procedure TForm1.Button1Click(Sender: TObject);
begin
Button1.Enabled := FALSE;
fAsyncCall := AsyncCall(WaitForIt, 1000);
end;
procedure TForm1.WaitForIt(ADelay: integer);
begin
Sleep(ADelay);
EnterMainThread;
try
Randomize;
Color := RGB(Random(256), Random(256), Random(256));
Timer1.Enabled := TRUE;
finally
LeaveMainThread;
end;
end;
Mentre l'operazione è attiva, non è possibile avviare altro. Al termine permette al timer per informare la forma e reimpostare il riferimento di interfaccia:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Timer1.Enabled := FALSE;
Assert((fAsyncCall <> nil) and fAsyncCall.Finished);
fAsyncCall := nil;
Button1.Enabled := TRUE;
end;
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
CanClose := (fAsyncCall = nil) or fAsyncCall.Finished;
end;
Nota come sia ancora possibile accedere al modulo direttamente dal metodo chiamato, utilizzando EnterMainThread()
e LeaveMainThread()
.
Sopra il codice non è il minimo assoluto, è destinato a dimostrare solo alcune idee.
Ho visto quella libreria ieri, ma volevo mantenere il codice minimo, penso che finirò per usarlo comunque. È una semplice unità .pas, giusto? – Sebastian
Sì lo è, solo tra 2 e 3 kLOC, quindi è già abbastanza minimale. Non penso che questo possa essere battuto. L'interfaccia è estremamente semplice, tutta la parte pelosa è nella parte 'implementation' ;-) Assicurati di mantenere i riferimenti' IAsyncCall' fino al termine della chiamata, altrimenti l'ultimo decremento del conteggio dei riferimenti verrà bloccato. – mghie
Sembra che questa sarà la soluzione migliore, grazie mille. – Sebastian
- 1. Come chiamare EnumSystemLocales in Delphi?
- 2. Come chiamare il codice DeviceIOControl in modo asincrono?
- 3. Chiamare in modo asincrono un comando in Symfony2
- 4. Come eliminare una cartella in modo asincrono
- 5. Componenti da evitare in Delphi
- 6. È possibile chiamare i cmdlet di PowerShell in modo asincrono?
- 7. Come caricare in modo asincrono una mappa google in AngularJS?
- 8. Creazione di componenti UI accessibili in Delphi
- 9. Python può chiamare le funzioni Delphi in una DLL?
- 10. Come gestire i componenti specifici del progetto in Delphi?
- 11. Come posso monitorare un file in modo asincrono in Perl?
- 12. Imposta Thread.CurrentPrincipal in modo asincrono?
- 13. come eseguire una funzione javascript in modo asincrono, senza utilizzare setTimeout?
- 14. Come leggere un file in modo asincrono?
- 15. Componenti controllo ortografico per Delphi
- 16. Come chiamare un'azione senza generare una vista in grails
- 17. Come posso chiamare un metodo statico Objective-c in modo asincrono?
- 18. Strategie per chiamare il servizio sincrono chiamate in modo asincrono in C#
- 19. Come posso elaborare xml in modo asincrono in python?
- 20. Come svuotare in modo asincrono un file mappato in memoria?
- 21. Come recitare in modo asincrono tramite callback API in node.js?
- 22. Reagire, caricamento asincrono per più sezioni/viste con diversi componenti
- 23. caricamento manubrio modello in modo asincrono
- 24. Creazione di componenti in fase di esecuzione - Delphi
- 25. Come acquisire l'output del processo in modo asincrono in PowerShell?
- 26. Come chiamare TryParse in modo dinamico?
- 27. Come posso creare componenti in React Native senza usare JSX?
- 28. Chiamare il metodo asincrono dal controller MVC
- 29. Chiamare un metodo asincrono da un metodo non asincrono
- 30. AngularJS: filtro di inizializzazione in modo asincrono
Ho una versione di quello che sto facendo in C# jeje, ora che sto cercando di tradurre in delphi (perché non voglio usare .NET) vedo quello che stai dicendo. Grazie. – Sebastian
Finalmente ho funzionato solo con un semplice BeginThread, non mi interessa veramente il risultato della procedura, deve solo fare qualcosa o uscire. Grazie per il tuo messaggio. – Sebastian