Aplikacja wielowątkowa z dostępem do bazy

0

Witam,
chciałem napisać aplikację wielowątkową (wątki tworzone dynamicznie bez określonej ilości wątków na początku). W wątku powinno zostać wykonane zapytanie do bazy danych, operacja na bazie w zależności od wyniku pirwszego zapytania i zamknięcie wątku. Chyba również dynamicznie powinno być tworzone połączenie do bazy TSQLConnection. Aha, chciałbym aby podczas tworzenia wątku był przekazywany parametr "id" wskazujący na zapytanie sql jakie ma wykonać wątek.

Proszę o wskazówki

1

Nie mam doświadczenia w bazach danych opartych o silniki. Jednak nie stoi chyba nic na przeszkodzie użycia klasy TThread. We wszystkim powinna pomóc lektura artyukułu na tej stronie: http://lukashp.pl/Artykul/Programowanie/Delphi/delphi-watki - ewentualnie w czystym WinAPI taki przykład ode mnie poniżej. Tylko u siebie chcąc przekazać jakiś Id liczbowy to po prostu rzutuj parametr dla tej funkcji WinAPI w stylu Pointer(Integer(666)).

Co do kodu poniżej to prosty wrapper na ddraw.dll, który sobie napisałem dla emulatora ZX Spin, który domyślnie nie uruchamia się w trybie obsługi emulowanego Joysticka na klawiaturze i trzeba pamiętać o naciśnięciu klawisza F7. Ta dllka robi to za mnie. Moduł dll_export.pas to potrzebne funkcje weyksportowane, kilka funkcji jest w stylu "dummy procedur". Takich jak poniżej. Gdyż są potrzebne dla kompatybilności z DirectX 7, których wymaga ten emulator. Ale ja nie przewiduje używania tak starego DX i poza tym emulator nie korzysta z ich kodów.

procedure DDInternalLock; stdcall;
begin
end;

Pozostałe potrzebne funkcje są stworzone przed słowem kluczowym exports w taki sposób jak poniżej:

function DirectDrawEnumerateA(lpCallback : TDDEnumCallbackA; lpContext : Pointer) : HResult; stdcall;
var
  OriginalDllH : THandle;
  DirectDrawEnumerateAOriginalFunc : function(lpCallback : TDDEnumCallbackA;
    lpContext : Pointer) : HResult; stdcall;
begin
  Result := DD_OK;
  OriginalDllH := LoadLibrary('SYSTEM32\ddraw.dll');
  if OriginalDllH > 0 then
  begin
    DirectDrawEnumerateAOriginalFunc := GetProcAddress(OriginalDllH, 'DirectDrawEnumerateA');
    if @DirectDrawEnumerateAOriginalFunc <> nil then
    begin
      Result := DirectDrawEnumerateAOriginalFunc(lpCallback, lpContext);
    end;
  end;
end;

A to kod głowny, mam nadzieję, że coś Tobie to wyjaśni. A więcej pewnie pomogą bardziej doświadczeni userzy. Gdyż a propos wątków w WinAPI dodam, że bardzo ważne jest aby funkcja obsługi wątku była koniecznie zdefiniowana ze słowem stdcall. Inaczej Pointer zawierający parametr przekaże do niej jakieś bzdety. A ja o tym długo nie pomyślałem, dopiero google i opis na MSDNie rozwiał moje wątpliwości. Także głównie o tym należy pamiętać. No chyba, ze chcesz się bawić tylko pod VCL.

library ddraw;

uses
  Windows,
  Messages,
  dll_export in 'dll_export.pas';

const
  Wait_MS = 358;
  Destination_Windows_class_Name = 'TSPINMainWindow';

var
  WindowFound : boolean;

function EnumForZxSpinWindow(AHandle : HWND; ALParam : LParam) : boolean; stdcall;
var
  S : string;
  Pid : DWORD;
  ControlName : array[0..255] of Char;
begin
  Result := True;
  S := PChar(ALParam);
  GetClassName(AHandle, ControlName, SizeOf(ControlName));
  if ControlName = S then
  begin
    GetWindowThreadProcessId(AHandle, Pid);
    if Pid = GetCurrentProcessId then
    begin
      SendMessage(AHandle, WM_KEYDOWN, VK_F7, 0);
      WindowFound := True;
      Result := True;
    end;
  end;
end;

function EnumThreadFunc(Param : Pointer) : DWORD; stdcall;
begin
  Result := 0;
  repeat
    Sleep(Wait_MS);
    EnumWindows(@EnumForZxSpinWindow, LParam(PChar(Param)));
  until WindowFound;
end;

var
  PC : PChar;
  ThreadId : Cardinal;
begin
  WindowFound := False;
  PC := Destination_Windows_class_Name;
  CreateThread(nil, 0, @EnumThreadFunc, PC, 0, ThreadId);
end.
0

id możesz przekazywać w konstruktorze wątku, natomiast samo połączenie może być jedno...

1 użytkowników online, w tym zalogowanych: 0, gości: 1