Laden...

Live-Such-Thread abbrechen, wenn sich vor Ende der Suche, die Suchanfrage geändert hat

Erstellt von gelöschtem Konto vor 13 Jahren Letzter Beitrag vor 13 Jahren 889 Views
Gelöschter Account
vor 13 Jahren
Live-Such-Thread abbrechen, wenn sich vor Ende der Suche, die Suchanfrage geändert hat

Hallo zusammen,
ich starte für eingegebene Suchwerte jeweils einen Thread, der eine List Filtert und diese dann einer Listview zuteilt. Obwohl die Threads beim zuteilen der Daten an die Listview synchronisiert sind kommt es vor, dass die Resultate in der Listview veraltet sind (nur bei extrem schneller Eingabe).

Nun möchte ich den vorhergehenden Thread beenden, bevor ich einen neuen Starte. Da dieser aber nicht in einer Schleife läuft, bleibt mir ja nur Abort(). Dies klappt zwar, aber nach ca. 20 Aborts schliesst Windows mein Programm und meldet das es ein Problem gibt. Was für eine Alternative habe ich, um den Thread abzubrechen?

157 Beiträge seit 2008
vor 13 Jahren

Ich verstehe das Problem noch nicht so ganz. Du lässt über mehrere Threads die gleiche Aktion mit verschiedenen Suchwerten laufen und synchronisierst alle fertigen Threads, damit die Ausgabe im ListView nicht durcheinander läuft. Und jetzt möchtest du eine gewisse Anzahl an Threads laufen lassen und nur neue aufmachen, wenn alte fertig sind, damit eben dieser Effekt nicht auftritt?

Bei mir kommt das Konzept nicht an, mehrere Suchen gleichzeitig zu starten. Vor allem würdest du mit dem Beenden eines Threads doch diese Suche zerschießen.

Ich hätts gern noch was genauer. 😃

1.552 Beiträge seit 2010
vor 13 Jahren

Hallo gijoe222,

Ich habe es so verstanden. Du startest eine Suche, diese dauert (ich nehme an) 5 Sekunden. Nach 2 Sekunden merkst du dass du das falsche Suchwort benutzt hast, dann startest du eine neue Suche und möchtest die alte suche beenden um die neue zu starten und zu vermeiden dass beide Suchen das selbe suchen. Du solltest deinen Thread zwar nicht über Thread.Abort() abbrechen, sondern der Thread-Methode sagen dass sie sich beenden soll. Generell kann ich sagen dass man Thread.Abort() vermeiden sollte. Wie mein Vorschlag funktionieren sollte siehst du ganz gut in folgenden Artikel. Ich empfehle dir diesen Artikel gründlich durchzulesen, eventuell auch die ganze Serie, da sie IMHO sehr gut geschrieben ist.
Thread Save Cancellation

Gruß
Michael

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

Gelöschter Account
vor 13 Jahren

@murox: Wenn ich mir die Canceler-Methode anschaue, dann klappt das nur mit while-Schleifen, oder sehe ich das falsch?

@bonzy
Also so läuft die "on the fly" Suche in der Praxis:
EIngabe "M" => Thread startet und sucht in ca. 1000 Einträgen nach "M" (ca. 2-3s)
Eingabe "Me" => neuer Thread startet (alter kann beendet werden)
EIngabe "Mei" => neuer Thread startet (alter kann beendet werden)
EIngabe "Meie => usw.

Jedesmal, wenn sich die Textbox (Suchfeld) ändert, wird ein Thread gestartet. Der Effekt dabei ist, dass die Liste sofort angepasst wird, was ich als Benutzer als sehr angenehm empfinde. Man muss auch nicht extra auf den Knopf "Suchen" klicken.

Es werden zwar sehr viele Threads gestartet, aber wie gesagt, der Echtzeit-Such-Effekt ist echt genial.

=>und ja genau, die einzelnen Threads dauern unter Umständen zu lange, obwohl sie über keine While-Schleife verfügen. Neue Threads werden immer eröffnet, auch wenn alte noch am laufen sind, das ganze läuft synchronisiert, sodass mir die Suchergebnisse nicht durcheinander laufen.

6.862 Beiträge seit 2003
vor 13 Jahren

Hallo,

beim eigentlichen Problem versteh ich nicht wieso das überhaupt besteht, da du ja schreibst

Neue Threads werden immer eröffnet, auch wenn alte noch am laufen sind, das ganze läuft synchronisiert, sodass mir die Suchergebnisse nicht durcheinander laufen. Dann ist es doch egal ob die alten ganz normal auslaufen oder nicht. Die brauchst du dann doch nicht explizit beenden wenn sie es eh tun nach wenigen Sekunden.

Allgemein ist dein Vorgehen aber wirklich nicht toll. Wenn du schreibst

EIngabe "M" => Thread startet und sucht in ca. 1000 Einträgen nach "M" (ca. 2-3s)
Eingabe "Me" => neuer Thread startet (alter kann beendet werden) hört sich das so an als wenn du die Ausgangsmenge jedes mal neu durchsuchst. Sowas ist natürlich vollkommen unnötig. Es reicht doch das jeweils vorherige Suchergebniss zu durchsuchen wenn nur zusätzliche Buchstaben zur Suche hinzukommen. Noch geschickter wäre es die Ausgangsmenge als Baum zu haben, mit den einzelnen Buchstaben als Knoten, weil dann bekommt man so ne Suche verdammt schnell hin.

Baka wa shinanakya naoranai.

Mein XING Profil.

Gelöschter Account
vor 13 Jahren

Das ist es ja gerade, die listview nimmt manchmal nicht die aktuellste Suchliste, obwohl die Threads synchron sind. Ist mir ein Rätsel.

X
1.177 Beiträge seit 2006
vor 13 Jahren

huhu,

so wie ich das verstehe kannst du die Threads nicht abbrechen, weil intern z.B. eine SQL-Abfrage durchgeführt wird - sieh Dir hierfür doch mal die Begin/End-Methoden von SqlCommand an.

Dass deine Listview nicht immer die aktuellen Ergebnisse bekommt liegt einfach daran, dass deine Threads nicht "hintereinander", so wie erstellt, ablaufen, sondern dass die "speziellere" Abfrage durchaus schneller sein kann. Das bedeutet:

Suche "M" -> Thread1 startet
Suche "ME" -> Thread2 startet
Thread2 Beendet -> Listbox aktualisieren
Thread1 beendet -> Listbox aktualisieren

das es in den meisten Fällen richtig ist, liegt eher daran, dass die Abfrage schneller ist, als der Benutzer einen neuen Buchstaben tippt.

Wie synchronisierst du denn die Threads?

Ich würde das ganze so abhandeln, dass immer nur das Ergebnis des leztten gestarteten Threads als gültiges Ergebnis für die Listbox betrachtet wird.

😃

Xynratron

Herr, schmeiss Hirn vom Himmel - Autsch!

Die Erfahrung zeigt immer wieder, dass viele Probleme sich in Luft auslösen, wenn man sich den nötigen Abstand bzw. Schlaf gönnt.

Gelöschter Account
vor 13 Jahren

Also der statische Search-Thread sieht kurzgefasst so aus:


private static void doSearch(){
  lock (lockSearch)
     { // Hier wird gesucht und per Invoke die Listview angepasst
     }
}

Und wenn ich einen Counter einfüge, dann zählt der der Reihe nach brav nach oben. Somit sollte doch das suchen UND das setzen der Listview synchron sein??

Natürlich werden dem Thread GUI und Seachstring per Paramter mitgegeben (Object[]).

Und auch wenn ich wahllos extrem schnell auf der Tastatur rumhacke, dann kommen die Threads trotzdem nicht durcheinander, also läuft das ganze doch synchron, oder nicht?