2010-09-27 23 views
6

Nunca he trabajado con hilos antes, y ahora estoy tratando de crear un hilo con una consulta para verificar el estado de la base de datos. La consulta es la siguiente:cómo escribir y ejecutar un hilo

select (*) as DBCount from v$datafile where status in 'OFFLINE';.

Esta consulta devuelve el número total de todas las bases de datos que están fuera de línea. Ahora quiero crear un hilo en Delphi que ejecutará esta consulta en el fondo de mi aplicación cuando la ejecute y muestre los resultados en una etiqueta.

+0

Eliminé la etiqueta pthread porque no era realmente compatible con la etiqueta delphi. – mghie

Respuesta

0

En Delphi hay TThread clase. Puede crear dicho hilo usando un asistente sencillo de Delphi IDE (en Turbo Delphi: Archivo-> Nuevo-> Proyectos Delphi-> Archivos Delphi-> Subproceso Obcjet). En su constructor crea una conexión a la base de datos, y en el método Execute puedes crear un bucle que consulta la base de datos, actualizar alguna variable global (NO declarada como threadvar) y esperar un tiempo.

+2

Poner el resultado en un 'threadvar' hará que sea imposible para cualquier otro hilo obtener el resultado. ¿Cómo va a ser útil? – mghie

+1

upps, perdón, mi error, por supuesto, esto debería ser una variable normal. –

+0

Me estoy preguntando por qué esta respuesta está downvoted (incluso a pesar del threadvar) ya que creo que es útil y le da al OP un lugar para comenzar y para comenzar a leer. Sería genial si SO solo permitiera un downvote motivado ... – Remko

7

El subprocesamiento múltiple es difícil. Puede ser mejor utilizar un marco de enhebrado simple como AsyncCalls.

A raíz de las discusiones StackOverlow le puede dar más información sobre cómo resolver su problema:

Delphi - Threading frameworks

How Do I Choose Between the Various Ways to do Threading in Delphi?

Delphi thread that waits for data, processes it, then resumes waiting

+0

Otro buen marco de enhebrado es la OmniThreadLibrary de gabr: P http://otl.17slon.com/ – Remko

+0

@Remko: Está incluido en los hilos a los que me refiero. – gabr

0

Aquí puede encontrar una discusión sobre el uso de hilos de base de datos.

Simple Thread Sample Delphi

Hay un código que puede ser muy útil para usted.

Atentamente.

1

Esto es bastante fácil de hacer usando AsyncCalls. Supongamos que su código no roscado se ve así (haciendo caso omiso de todo el manejo de errores):

Query := 'select (*) as DBCount from...'; 
ExecuteSQL(SqlConnection,Query); 
SqlResult := GetSqlResult(SqlConnection); 
SqlRow := GetSqlRow(SqlResult); 
MyLabel.Text := SqlRow[0]; 
...Go on to do other things... 

Cuando la segunda línea es el bloqueo (en espera de que el servidor responda). El nuevo código se vería así:

uses AsyncCalls;  //added to your existing uses statement 
... 
procedure DoesSomething(); 
var Thread: TAsyncCall;    //your interface to AsyncCalls 
    procedure AsyncSqlCall();    //this is a LOCAL procedure 
    Query := 'select (*) as DBCount from...'; 
    ExecuteSQL(SqlConnection,Query); 
    SqlResult := GetSqlResult(SqlConnection); 
    SqlRow := GetSqlRow(SqlResult); 
    EnterMainThread; 
    try 
     Assert(GetCurrentThreadId = MainThreadId); 
     MyLabel.Text := SqlRow[0]; 
    finally 
     LeaveMainThread;   
    end; 

begin       //this begins proc DoSomething() 
    ... 
    Thread := LocalAsyncCall(@AsyncSqlCall); 
    ...Go on to do other things... 
end; 

único que hemos hecho es poner las llamadas de bloqueo de SQL en un proc local y dicho AsyncCalls para ejecutarlo en otro hilo, mientras que el hilo principal continúa ejecutándose. La única parte difícil fue usar el VCL, que no es seguro para subprocesos. Así que tuve esa línea segura en el hilo principal.

Si en algún momento usted necesita estar seguro de que el hilo asíncrono ha completado, usted ejecutaría esta línea para bloquear el hilo principal hasta AsyncSqlCall termina:

Thread.sync; 

Lo realmente agradable aquí es que AsyncCalls maneja todo lo de crear un grupo de subprocesos, crear subprocesos, etc. Aunque no se muestra en este ejemplo, puede pasar variables a su subproceso y devolver un valor. No tiene que usar un programa local, pero al hacerlo, tiene acceso a todos los vars locales. Podrías hacer todo esto global, y luego lanzar el hilo Async en una rutina y probar su finalización en otra.

Restricciones:

Su hilo asíncrono no debe tocar (lectura o escritura) nada más que sus propias variables, y su hilo principal no debe tocar mientras el hilo asíncrono se está ejecutando. USTED debe codificarlo de esa manera. Nada te impedirá crear un caos total. En el ejemplo anterior, su hilo principal no debe tocar Consulta, SqlConnection, SqlResult y SqlRow. Si alguna parte de tu código usaba uno de esos valores antes de la llamada Thread.sync, tu código funcionaría, pero lanzaría excepciones en lugares extraños que nunca esperaste. Así que mantenlo simple.

Su subproceso Async no debe usar el VCL. El ejemplo anterior muestra una de varias formas de evitar de forma segura esta limitación.

Por último:

AsyncCalls no es un marco completo Multi-Threading. Es solo una forma de llamar a las funciones de procs & de forma asíncrona (es decir, sin esperar). No intentes llevarlo demasiado lejos, con lo que quiero decir, no trates de convertirlo en la base de un programa totalmente multitarea.

Cuestiones relacionadas