in DB suchen während Eintippen ohne Verzögerung



  • Hallo,

    ich möchte mittels eines Editfeldes schon bei der Texteingabe in einer Datenbank suchen. (Es soll so ungefähr funktionieren, wie bei Google).

    Ich dachte, damit der Benutzer in seiner Eingabe in das Editfeld nicht von der Suche gehnidert wird (sprich, damit es keine Verzögerung bei der Benutzereingabe gibt), stelle ich die Suche in einem separaten Thread. Und damit das Suchergebnis schneller angezeigt werden kann, nutze ich direkt die DBGrid, ADOQuery und DataSource Komponenten und verbinde sie miteinander.

    Trotzdem gibt es bei einem großen Suchergebnis eine leichte Verzögerung beim Eintippen in das Editfeld.

    Meine Frage: Wie kriege ich diese Verzögerung weg, so dass der Benutzer fließend seinen Text eintippen kann?

    Für jeden Tipp bin ich dankbar.



  • Ich habe keine Ahnung, wie dein Abfragethread aussieht, aber du kannst

    a) dem Thread eine niedrigere Priorität geben
    b) Im Thread hin und wieder ein Sleep( 0 ) aufrufen, um die CPU abzugeben

    Wenn der Thread allerdings in Codeabschnitten steckt, auf die du keinen Einfluss hast bleibt dir nur Möglichkeit a) und zu hoffen, dass es funktioniert.



  • Hier mein Code:

    __fastcall TMySeeker::TMySeeker(bool CreateSuspended) : TThread(CreateSuspended)
    {
      FreeOnTerminate = true;
    }
    //---------------------------------------------------------------------------
    __fastcall TMySeeker::~TMySeeker()
    {
      MySeeker = NULL;
    }
    //---------------------------------------------------------------------------
    void __fastcall TMySeeker::Execute()
    {
      try
      {
        Synchronize(ThreadExecute);
      }
      __finally
      {
        Terminate();
      }
    }
    //---------------------------------------------------------------------------
    void __fastcall TMySeeker::ThreadExecute()
    {
      try
      {
        Form2->DBGrid1->DataSource = NULL;
        Form2->ADOQuery1->Close();
        Form2->ADOQuery1->SQL->Clear();
        Form2->ADOQuery1->SQL->Add("..."); //eine ganz normale SELECT
        Form2->ADOQuery1->Open();
      }
      __finally
      {
        if(Form2->ADOQuery1->RecordCount > 0)
        {
          Form2->DBGrid1->DataSource = Form2->DataSource1;
          Form2->DBGrid1->Visible = true;
        }
      }
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm2::Edit1Change(TObject *Sender)
    {
      if(MySeeker == NULL)
        MySeeker = new TMySeeker(false);
    
    }
    //---------------------------------------------------------------------------
    


  • ich glaube das liegt an deinem falschen Synchronize. Das sollte nach der SQL Abfrage kommen und dabei die Ergebnisse zur Form übertragen. Die eigentliche SQL Abfrage läuft momentan nämlich nicht wirklich in einem eigenen Thread, wenn ich das richtig sehe.

    greetz KN4CK3R



  • Hallo

    KN4CK3R hat Recht, dein Thread ist zur Zeit witzlos. Die Abfrage muß aus der Synchronize-Methode raus in die normale Execution-Methode. Die Ergebnisse der Abfrage kommen dann in eine passende Member-Variable der Thread-Klasse, dann Synchronize aufrufen wo nur noch die Ergebnisse auf die GUI übertragen werden.

    Ja, das bedeutet das du für deinen Thread sowieso keine GUI-Elemente benutzen kannst.ADOQuery ist in Ordnung (aber die Instanz sollte nicht zu einem Form gehören, sondern nur zum Thread). Aber ein DBGrid kannst du nicht direkt verwenden, um die Ergebnisse anzuzeigen. Wechsle das mit einem TListBox/TStringGrid/TListView aus, in das du die Ergebnisliste in der Synchronize-Methode manuell reinkopierst.

    bis bald
    akari



  • OK.
    Vielen Dank für die Antworten.


Log in to reply