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.
Eliminé la etiqueta pthread porque no era realmente compatible con la etiqueta delphi. – mghie