2011-03-08 19 views
12

¿Alguien puede publicar el ejemplo del hilo más simple para Delphi 2010 que, por ejemplo, pone algo de texto en una nota cuando se hace clic en el botón? Con implementación y todo. Gracias.Hilos de Delphi 2010

Actualización: Ok, solo un hilo simple que hace algo. No hay necesidad de una nota. Gracias.

+5

¿Por qué le gustaría un hilo para poner texto en una nota? De hecho, es casi el peor ejemplo imaginable porque el código UI necesita ejecutarse en el hilo principal. –

+4

@David: es útil para cosas como informar el estado al usuario. es decir, un hilo ejecuta una búsqueda en el disco en busca de malware. Tiene que informar el progreso, "hits", etc., de vuelta al hilo principal. Es probable que necesite hacer eso a través de Sincronizar. –

+2

@Chris Tiendo a evitar 'Sincronizar', que es bastante pesado y resuelve el problema de manera diferente. –

Respuesta

13

Hay una buena demostración de hilo, incluida GUI/Sincronizar, que se envía con Delphi. En D2005, está en: C: \ Archivos de programa \ Borland \ BDS \ 3.0 \ Demos \ DelphiWin32 \ VCLWin32 \ Threads

2

Como se ha señalado, crear un hilo para actualizar la GUI no es un buen diseño . Sería mejor que sus hilos hagan un trabajo real y permitan que el hilo principal actualice su pantalla.

Aunque Delphi también ofrece la clase TThread para facilitar la creación/administración de subprocesos, también puede utilizar la función BeginThread de Delphi para ejecutar subprocesos sencillos. Hay una página web example on the Delphi Basics, que he reproducido aquí:

// Full Unit code. 
// ----------------------------------------------------------- 
// You must store this code in a unit called Unit1 with a form 
// called Form1 that has an OnCreate event called FormCreate. 

unit Unit1; 

interface 

uses 
    Forms, Dialogs, Windows, SysUtils; 

type 
    TMsgRecord = record 
    thread : Integer; 
    msg : string[30]; 
    end; 
    TForm1 = class(TForm) 
    procedure FormCreate(Sender: TObject); 
    end; 

var 
    Form1: TForm1; 

Implementation 
{$R *.dfm}  // Include form definitions 

ThreadVar   // We must allow each thread its own instances 
        // of the passed record variable 
    msgPtr : ^TMsgRecord; 

// Private thread procedure to show a string 
function ShowMsg(Parameter : Pointer) : Integer; 
begin 
    // Set up a 0 return value 
    Result := 0; 

    // Map the pointer to the passed data 
    // Note that each thread has a separate copy of msgPtr 
    msgPtr := Parameter; 

    // Display this message 
    ShowMessagePos('Thread '+IntToStr(msgPtr.thread)+' '+msgPtr.msg, 
       200*msgPtr.thread, 100); 

    // End the thread 
    EndThread(0); 
end; 

procedure TForm1.FormCreate(Sender: TObject); 
var 
    id1, id2 : LongWord; 
    thread1, thread2 : Integer; 
    msg1, msg2 : TMsgRecord; 

begin 
    // set up our display messages 
    msg1.thread := 1; 
    msg1.msg := 'Hello World'; 
    msg2.thread := 2; 
    msg2.msg := 'Goodbye World'; 

    // Start the first thread running asking for users first name 
    thread1 := BeginThread(nil, 
         0, 
         Addr(ShowMsg), 
         Addr(msg1), 
         0, 
         id1); 

    // And also ask for the surname 
    thread2 := BeginThread(nil, 
         0, 
         Addr(ShowMsg), 
         Addr(msg2), 
         0, 
         id2); 

    // Ensure that the threads are only closed when all done 
    ShowMessagePos('Press this when other dialogs finished.', 200, 300); 

    // Finally, tidy up by closing the threads 
    CloseHandle(thread1); 
    CloseHandle(thread2); 
end; 

end. 

Aquí también es another example de cómo utilizar hilos con los parámetros (utilizando BeginThread).

+0

Gracias, ¿pueden publicar un ejemplo simple utilizando una clase TThread? –

+0

No creo que el código de ejemplo deba contener un código problemático como este (ejecutar el código de la GUI de VCL en el contexto de subprocesos secundarios). – mghie

+0

@mghie - Consideré no publicarlo, pero lo llamé mal diseño en mi comentario. Dejaré que otros decidan si quieren tomar buenas o malas decisiones de diseño después de que les haya informado del problema. – Mick

11

ejemplo más simple que puedo imaginar: (Suponga que tiene Memo1 en Form1)

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    TThread.CreateAnonymousThread(procedure 
     var 
     slThread: TStringList; 
     i: Integer; 
     begin 
      //do something in thread 
      slThread := TStringList.Create; 
      try 
      for i := 0 to 100 - 1 do 
      begin 
       slThread.Add(Format('Value %D',[i])); 
      end; 

      //update gui 
      TThread.Synchronize(nil, procedure 
      begin 
       Form1.Memo1.Lines.AddStrings(slThread); 
      end); 


      finally 
      slThread.Free; 
      end; 


     end).Start; 
end; 

Aunque no voy a recomendar el uso de ella, ya que tiene algunas desventajas. Es mejor bajar tu propia clase TThread, pero para tu pregunta, este ejemplo encaja muy bien.

+0

+1 para usar métodos anónimos y una de las últimas versiones de Delphi. –

+0

es el 'nil,' después de 'TThread.Synchronize (' necesario aquí? (No lo creo) – mjn

+0

Es el parámetro de instancia de TThread. Debido a que no lo declaramos en este ejemplo, debemos pasar nil. – Linas

Cuestiones relacionadas