2010-03-29 12 views
5

Pregunta de novato: Tengo una aplicación de formularios. Tiene un hilo separado que hace una llamada de servicios web, y luego publica los resultados de la llamada al formulario principal.¿Debo liberar un objeto Delphi automáticamente de una llamada a servicios web?

En mi hilo, después de X segundos han pasado (utilizando un TTimer), que llame a:

procedure TPollingThread.OnTimer(Sender: TObject); 
var 
SystemProbeValues : TCWProbeValues; 
begin 
SystemProbeValues := Remote.Run.GetSystemProbeValues; 
PostMessage(ParentHandle, WM_APIEVENT ,Integer(apiMultiCellStatus), Integer(SystemProbeValues)); 
end; 

Los Remote.Run.GetSystemProbeValues ​​función tiene el siguiente prototipo:

function GetSystemProbeValues : TCWProbeValues; stdcall; 

Y TCWProbeValues es una matriz dinámica de objetos TCWProbeValue (que todos descienden de TRemotable).

En mi forma principal, recibo el mensaje de bien y tire la LParam de nuevo a TCWProbeValues:

procedure TFrmCWMain.OnAPIEvent(var msg: TMessage); 
begin 
ProbeValues := TCWProbeValues(msg.LParam); 
end; 

Mi pregunta es, dado que la matriz dinámica y sus objetos fueron creados por el sistema Delphi HTTORIO, ¿Quién es responsable de liberarlos? ¿Delphi consideró que la memoria se podía reutilizar después de que se devolviera la función OnTimer? (¿Y en ese caso, es pura suerte que mi manejador principal de mensajes de formulario realmente pueda leer la memoria a la que hace referencia el LParam del mensaje?) O más bien, ¿es mi responsabilidad liberar el objeto autoinstanciado por la solicitud HTTPRIO?

Muchas gracias, por favor griten si lo anterior necesita más detalles/código y ¡lo agregaré!

Cheers, Duncan

Respuesta

4

TRemotable proporciona gestión de vida a través de su propiedad DataContext, por lo que el tiempo de ejecución de SOAP liberará el objeto en sí. Mientras exista el objeto de contexto de datos, todo lo que haya asignado también existirá. Si desea reclamar la propiedad y la responsabilidad de un objeto, simplemente borre su propiedad DataContext. (Eso es probablemente lo que usted quiere hacer en este caso debido a que su mensaje API-evento puede obtener manejado después del evento de SOAP ha terminado.)


un problema en su código es que estás pasando una dinámica matriz a través de un mensaje publicado. Cuando su procedimiento OnTimer regrese a su llamador, la matriz dinámica a la que hace referencia SystemProbeValues tendrá su contador de referencia decrementado. Si el otro hilo aún no ha procesado el mensaje (y probablemente no lo haya hecho), entonces el conjunto dinámico ya puede estar destruido cuando hace para procesar ese mensaje.

La forma más fácil de hacerlo es borrar la referencia en el controlador de eventos del temporizador sin reducir el recuento de referencias, y luego hacer lo contrario en el controlador de mensajes. Después de contabilizar el mensaje, borrar la variable:

LParam(SystemProbeValues) := 0; 

En su controlador de mensajes, borrar el valor antiguo de la ProbeValues variable global y asignar el nuevo valor de la siguiente manera:

ProbeValues := nil; 
LParam(ProbeValues) := Msg.LParam; 

Otro El problema al acecho en su código puede ser el uso de TTimer en un hilo no VCL. Esa clase crea un identificador de ventana para compartir entre todas las instancias de la clase.A menos que el subproceso del temporizador sea el único subproceso del programa que usa TTimer, es probable que tenga problemas, ya sea con funciones que se ejecutan en el subproceso incorrecto o funciones que no se ejecutan en absoluto. En lugar de TTimer, puede usar SetTimer para crear un temporizador de sistema operativo manualmente, o puede crear un waitable timer, que puede ser más adecuado para usar en un hilo que no necesita seguir siendo receptivo a las acciones del usuario.

Cuestiones relacionadas