Revisando el código, probando linea por linea, comparándolo con el ejemplo de multi threading que viene con Lazarus, no encontraba el error, usaba lo que tenía que usar, todo en su lugar... eso creía yo.
Esto es una sugerencia basada en mi experiencia: Si preguntan en algún foro, y esperan una respuesta rápida, pregunten en foros en idioma Inglés, cuando he preguntado en foros en español, o no me contestan, o tardan millones de años.
Bueno lancé la pregunta en el foro de Lazarus y en Stack Overflow, minutos mas tarde ya me estaban respondiendo con algunos tips, y comentarios de lo que podría estar fallando o faltando en mi proyecto.
En resumen la cuestión era que si se van a usar threads en Linux(UNIX, OsX BSD y demás) es necesario agregar al archivo ".lpr" del proyecto (este archivo es creado automaticamente al crear un proyecto, en el directorio del proyecto) necesitamos agregar la siguiente linea:
{$define UseCThreads}
Quedando de la siguiente forma el documento:
{$mode objfpc}{$H+} {$define UseCThreads} uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Interfaces, // this includes the LCL widgetset Forms, Unit1 { you can add units after this }; . . .
Una vez agregado esto y recompilando, funcionó.
Bueno voy a agregar el pequeño ejemplo:
Comienzan un nuevo proyecto en Lazarus->aplicación, y agregara un form vacío, agregamos un botón y un progressbar para el ejemplo.
unit Unit1; {$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, ComCtrls; //Creamos el type para lo que será nuestro hilo type { TMiHilo } TMiHilo = class(TThread) private procedure AvanzaBarra; protected procedure Execute; override; public constructor Create(CreateSuspended: boolean); end; { TForm1 } TForm1 = class(TForm) Button1: TButton; ProgressBar1: TProgressBar; procedure Button1Click(Sender: TObject); private { private declarations } public { public declarations } end; var Form1: TForm1; implementation {$R *.lfm} { TForm1 } //agregamos al evento click del botón, aquí se iniciará nuestro hilo al dar click procedure TForm1.Button1Click(Sender: TObject); var MiHilo : TMiHilo; begin //creamos el hilo, pero no lo iniciamos MiHilo := TMiHilo.Create(True); // Con el parametro true no se inicia automaticamente if Assigned(MiHilo.FatalException) then raise MiHilo.FatalException; //si no hay ninguna excepción lo iniciamos MiHilo.Start; end; //aquí definimos los procesos para el hilo { TMiHilo } procedure TMiHilo.AvanzaBarra; //Este metodo solo es llamado por Synchronize(@AvanzaBarra) y por ello // es ejecutado por el hilo principal. //El hilo principal puede acceder a los elementos visuales del GUI por ejemplo a la progressbar begin Form1.ProgressBar1.StepIt; if Form1.ProgressBar1.Position = Form1.ProgressBar1.Max then begin Form1.ProgressBar1.Position := 0; end; end; //Este proceso se ejecuta al iniciar el hilo procedure TMiHilo.Execute; begin //mientras no termine y sea verdadero se ejecutará while (not Terminated) and (true) do begin //este loop es del hilo principal Synchronize(@AvanzaBarra); end; end; constructor TMiHilo.Create(CreateSuspended: boolean); begin //Con esta propieda del hilo no necesitamos liberarlo manualmente al terminar de ejecutar el hilo FreeOnTerminate := True; inherited Create(CreateSuspended); end; end.
Y listo, compilamos y ejecutamos y debemos ver nuestro formulario con un botón y una barra de progreso, al dar clic en el botón esta comenzará a llenarse, cuando se llene se vaciará y comenzara de nuevo. No olviden agregar la linea {$define UseCThreads} en el archivo .lpr de su proyecto para que la validación de "si es compilado en Unix" use cThreads.
No hay comentarios:
Publicar un comentario