J'essaie d'exécuter une fonction ou une procédure dans Delphi de manière asynchrone, mais sans utiliser de composant, y a-t-il un moyen de le faire avec les fonctions delphi?Comment appeler une fonction/procédure de manière asynchrone dans Delphi (sans composants)
Répondre
Vous pouvez également exécuter votre procédure sur un thread. Utilisez ensuite l'événement OnTerminate pour obtenir le résultat. Oui, en ces jours de .NET et C# nous sommes une sorte de gâté avec la forme facile et pratique de l'exécution des méthodes asynchronioulsly, mais c'est la façon dont cela fonctionne sur Delphi.
Si vous demandez si la VCL a quelque chose de prêt à l'emploi like BeginInvoke in .NET, alors la réponse est non. Cependant, vous pouvez obtenir quelque chose de très similaire sous la forme d'une petite unité que vous liez à votre programme, la bibliothèque AsyncCalls par Andreas Hausladen. Ce n'est pas une composante, donc je suppose que cela se qualifie. Il prend également en charge Delphi à partir de la version 5. Très recommandé
Edit:
Je vais ajouter un exemple puisque vous ne l'avez pas en cours d'exécution. Si vous obtenez un blocage dans votre code d'appel, votre problème est qu'aucune référence n'est conservée au pointeur d'interface IAsyncCall
renvoyé par la fonction. L'objet implémentant l'interface sera donc détruit immédiatement lorsque la référence temporaire sortira de sa portée. Le destructeur sera appelé dans le contexte du thread VCL, et il appellera WaitForSingleObject()
ou une fonction similaire pour attendre la fin du thread de travail. Le résultat de cela est que votre thread VCL bloque.
Vous obtiendrez le comportement correct si vous maintenez une référence au pointeur d'interface:
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;
Réglez la minuterie est désactivé et laissez-il un très court Interval
, disons 50 ms. Le clic sur le bouton lance l'opération asynchrone:
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;
Lorsque l'opération est active, aucune autre opération ne peut être lancée. A la fin, il permet la minuterie de notifier le formulaire et réinitialiser la référence de l'interface:
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;
Notez comment il est même possible d'accéder au formulaire directement à partir de la méthode appelée, en utilisant EnterMainThread()
et LeaveMainThread()
.
Au-dessus du code n'est pas le minimum absolu, il est destiné à démontrer quelques idées seulement.
J'ai vu cette bibliothèque hier, mais je voulais garder le code minimal, je pense que je vais finir par l'utiliser quand même. C'est une simple unité .pas, n'est-ce pas? – Sebastian
Oui c'est, seulement entre 2 et 3 kLOC, donc c'est déjà assez minime. Je ne pense pas que cela puisse être battu. L'interface est extrêmement simple, tous les trucs poilus sont dans la partie 'implementation' ;-) Assurez-vous juste de garder les références' IAsyncCall' jusqu'à ce que l'appel soit terminé, sinon le dernier décompte du nombre de références bloquera. – mghie
On dirait que ce sera la meilleure solution, merci beaucoup. – Sebastian
- 1. Comment appeler une méthode statique Objective-c de manière asynchrone?
- 2. Comment appeler ce service Web de manière asynchrone?
- 3. Comment appeler une méthode de manière asynchrone? Dois-je créer une classe dérivée de IAsyncResult?
- 4. plusieurs webrequests de manière asynchrone dans asp.net?
- 5. Comment appeler une DLL Delphi de VB6
- 6. Comment appeler une page asp.net en utilisant de manière asynchrone JQuery
- 7. Delphi appeler une DLL
- 8. Ouverture d'une boîte de dialogue Modal de manière asynchrone dans Delphi
- 9. Comment utiliser HttpWebRequest (.NET) de manière asynchrone?
- 10. Copie dirigée de manière asynchrone
- 11. Comment exécuter une commande système en Perl de manière asynchrone?
- 12. Appel du service WCF de manière asynchrone dans une boucle
- 13. Sérialisation des composants Delphi
- 14. Pourquoi utiliser ReadDirectoryChangesW de manière asynchrone?
- 15. NServiceBus - Comment appeler NSB via le service Web mais de manière asynchrone?
- 16. Delphi - Composants installés perdus
- 17. manière correcte de maximiser forme delphi (sans légende)
- 18. Comment initier plusieurs requêtes HTTP de manière asynchrone?
- 19. La manière correcte d'ignorer un délégué asynchrone
- 20. ASP.NET/WCF - Execute Server.Execute de manière asynchrone
- 21. Threading.Timer appelle plusieurs méthodes de manière asynchrone
- 22. asynchrone sans état API
- 23. Exécution de tâches lentes de manière asynchrone dans Rails?
- 24. Erreur envoi de courrier de manière asynchrone
- 25. Accès multithread des composants dans Delphi
- 26. Impossible d'envoyer le courrier de manière asynchrone
- 27. Composants non visuels sans formulaires
- 28. XMLRPCPP traitant de manière asynchrone plusieurs appels?
- 29. Comment interroger de manière asynchrone un fichier à l'aide d'une minuterie flash sans bloquer l'interface utilisateur?
- 30. Appel d'une méthode de manière asynchrone
J'ai une version de ce que je fais dans C# jeje, maintenant que j'essaie de traduire en Delphi (parce que je ne veux pas utiliser .NET), je vois ce que vous dites. Merci. – Sebastian
Je l'ai finalement fait fonctionner avec un simple BeginThread, je ne me soucie pas vraiment du résultat de la procédure, il suffit de faire quelque chose ou de sortir. Merci pour votre message. – Sebastian