Estoy intentando ejecutar una función o procedimiento en Delphi de forma asíncrona, pero sin utilizar un componente, ¿hay alguna manera de hacerlo con las funciones delphi core?Cómo llamar a una función/procedimiento de forma asíncrona en Delphi (Sin componentes)
Respuesta
Es posible que también desee ejecutar su procedimiento en un hilo. Use luego el evento OnTerminate para obtener el resultado. Sí, en estos días de .NET y C# estamos algo mimados con la forma fácil y conveniente de ejecutar métodos asincrónicamente, pero así es como funciona en Delphi.
Si está preguntando si el VCL tiene algo like BeginInvoke in .NET listo para usar, entonces la respuesta es no. Sin embargo, puede obtener algo muy similar en la forma de una pequeña unidad que vincula a su programa, la biblioteca AsyncCalls de Andreas Hausladen. No es un componente, así que supongo que califica. También es compatible con Delphi desde la versión 5 en adelante. Muy recomendado
Editar:
Voy a añadir un ejemplo ya que usted no ponerlo en marcha. Si obtiene un bloqueo en su código de llamada, entonces su problema es que no se mantiene ninguna referencia al puntero de interfaz IAsyncCall
que devolvió la función. El objeto que implementa la interfaz se destruirá inmediatamente cuando la referencia temporal salga del alcance. Se llamará al destructor en el contexto del hilo VCL, y llamará al WaitForSingleObject()
o una función similar para esperar a que termine el hilo del trabajador. El resultado de eso es que su hilo VCL bloquea.
obtendrá el comportamiento correcto si se mantiene una referencia al puntero de interfaz:
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;
Ajuste el temporizador debe ser inhabilitado y hacer que tenga un tiempo muy corto Interval
, dicen que 50 ms. El clic de botón inicia la operación asíncrona:
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;
Mientras la operación está activa no se puede iniciar ninguna otra. Al finalizar el temporizador que permite notificar a la forma y restablecer la referencia de interfaz:
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 cómo es posible incluso para acceder al formulario directamente desde el método llamado, mediante el uso de EnterMainThread()
y LeaveMainThread()
.
El código anterior no es el mínimo absoluto, solo pretende demostrar algunas ideas.
Vi esa biblioteca ayer, pero quería mantener el código mínimo, creo que terminaré utilizándolo de todos modos. Es una unidad .pas simple ¿verdad? – Sebastian
Sí, lo es, solo entre 2 y 3 kLOC, por lo que ya es bastante mínimo. No creo que esto sea inmejorable. La interfaz es extremadamente sencilla, todas las cosas peludas están en la parte de 'implementación' ;-) Solo asegúrate de mantener las referencias 'IAsyncCall' hasta que la llamada haya finalizado, de lo contrario se bloqueará la última disminución del recuento de referencia. – mghie
Parece que esta será la mejor solución, muchas gracias. – Sebastian
- 1. Cómo llamar a cualquier método de forma asíncrona en C#
- 2. Cómo eliminar una carpeta de forma asíncrona
- 3. Serialización de componentes Delphi
- 4. Desplazamiento sincronizado Componentes Delphi
- 5. jQuery - Enviar una forma asíncrona
- 6. Cómo llamar a NSBeep desde Delphi
- 7. ¿Cómo puedo monitorizar de forma asíncrona un archivo en Perl?
- 8. ¿Cómo llamar a TryParse de forma dinámica?
- 9. JavaScript: ¿Cómo descargar JS de forma asíncrona?
- 10. ¿Es posible llamar a los cmdlets de PowerShell de forma asíncrona?
- 11. WinForms RichTextBox: Cómo volver a formatear de forma asíncrona, sin disparar TextChanged caso
- 12. Descargar pdf de forma asíncrona
- 13. Cómo llamar a la función WinAPI SetDllDirectory() en Delphi?
- 14. Criando eventos de forma asíncrona
- 15. ¿Cuál es la forma más sencilla de llamar a Http GET url usando Delphi?
- 16. escribo de forma asíncrona a presentar en Perl
- 17. Componentes de escaneo TWAIN para Delphi
- 18. Llamada a función asíncrona en Flex
- 19. Escribir en un archivo de forma asíncrona
- 20. Componentes en Delphi y C++ Builder?
- 21. ¿Cómo vaciar de forma asíncrona un archivo mapeado en memoria?
- 22. Llamar a una función delphi DLL desde C# Code
- 23. Llamar a C# dll desde Delphi
- 24. Delphi: ¿Está bien para una forma liberarse?
- 25. Componentes de corrección ortográfica para Delphi
- 26. ¿Cuál es la forma más sencilla de llamar a Http POST url usando Delphi?
- 27. ¿Cómo llevar una vista al frente sin llamar a bringToFront()?
- 28. ¿Está bien registrar componentes en Windsor sin especificar una interfaz?
- 29. ¿Cómo puedo consultar la paleta de componentes Delphi?
- 30. Cómo llamar a CMD sin abrir una ventana
Tengo una versión de lo que estoy haciendo en C# jeje, ahora que estoy tratando de traducir a delphi (porque no quiero usar .NET) veo lo que estás diciendo. Gracias. – Sebastian
Finalmente lo tengo trabajando con un simple BeginThread solamente, realmente no me importa el resultado del procedimiento, solo tiene que hacer algo o Salir. Gracias por su mensaje – Sebastian