laufenden Thread suchen

  • VB.NET

Es gibt 20 Antworten in diesem Thema. Der letzte Beitrag () ist von thefiloe.

    laufenden Thread suchen

    Folgendes Problem.
    Ich habe einen Thread deklariert und gestartet.
    Diesen möchte ich jetzt mittels "Abort" abbrechen, allerdings ist die deklaration des Threads nicht global, so das ich nicht an jeder Stelle direkt darauf zu greifen kann.

    Kann ich jetzt irgendwie den Thread anhand seines Namens suchen und dann abbrechen?

    x90cr schrieb:

    anhand seines Namens suchen
    Hast Du ihm einen Namen gegeben?
    Bei Stackoverflow ist man nicht glücklich geworden, Threads per Name zu "picken".
    Threads "mit dem Holzhammer anzuschießen" ist nicht gut.
    Üblicherweise sollte ein Thread sich selbst beenden, also wenn seine Arbeit getan ist oder wenn von außen gesagt wird, dass er sich verabschieden soll.
    Setze ein entsprechendes Flag, das dem Thread sagt, dass er die Threadprozedur verlassen soll.
    Das ist der Plan. :D
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Dim thread1 As New System.Threading.Thread(AddressOf ausfuehren)

    Das ist mir bekannt, die "Abort" Funktion soll auch nur angewendet werden wenn ein "sofortiges" Abbrechen unumgänglich ist.
    Ansonsten hab ich das schon so gestaltet das nach jedem Zwischenschritt im Thread zum Ende gesprungen wird wenn die entsprechende Variable gesetzt wurde.
    @x90cr Ich würde jetzt die Deklaration in die Klasse reinnehmen und feddich.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    x90cr schrieb:

    mit aufgerufen werden würde.

    VB.NET-Quellcode

    1. ' Klasse
    2. Private thread1 As System.Threading.Thread
    3. ' Sub
    4. thread1 = New System.Threading.Thread(AddressOf ausfuehren)
    5. ' Abbruch:
    6. If thread1 IsNot Nothing AndAlso thread1.IsAlive Then
    7. thread1.Abort()
    8. End If
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Sieht gut aus Danke.

    Dafür habe ich gleich das nächste Problem, vielleicht kannst du mir da auch noch helfen.
    Im besagten Thread wird in einem bestimmten Teilabschnitt unter ungünstigen Bedingungen fortlaufend in ein Listview geschrieben die im Thread der Form läuft.
    Problem ist jetzt das die Zugriffe auf die Listview eine Benutzung des "Abbrechen Buttons" nicht erlauben.

    Ich bräuchte jetzt eine einfach Möglichkeit das zu umgehen.
    Der einfachste Weg den ich mir vorstellen kann, aber nicht weiss wie ich ihn umsetzen kann, wäre einen extra Thread zu starten der ein Key_Down Event der Tastatur abfangen kann.

    x90cr schrieb:

    Problem ist jetzt das die Zugriffe auf die Listview eine Benutzung des "Abbrechen Buttons" nicht erlauben.
    Kannst Du das etwas näher erläutern?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Der Button sowie die Listview liegt auf der Main Form und läuft somit auch in dessen Thread.
    Der besagte "Thread1" schickt jetzt Items an die Listview.
    Und solange wie Thread1 auf die Listview zugreift, ist der Hintergrundthread der Main Form damit beschäftigt die Listview zu füllen und kann den Button somit nicht verarbeiten.

    Da im ungüstigsten Fall aber mehrere Einträge pro Sekunde stattfinden, hat man keine Möglichkeit den Button zu nutzen.
    Im Thread (in einer Schleife) könntest Du mit GetAsyncKeyState() die Tastatur abfragen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Warum mehrere Einträge pro Sekunde? Sammle die Ergebnisse und invoke nur alle paar Sekunden oder alle 50 Einträge (Beispiel).
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    Die Einträge zu sammeln ist auch nicht ganz einfach, mit jedem Schleifendurchgang werden 5 Zeilen gleichzeitig hinzugefügt und jede in einer anderen Farbe.

    Ich habe das Problem jetzt aber ganz einfach lösen können, in dem ich nach jedem Schleifendurchgang einen kurzen "Sleep" fahre mit 50ms.
    Würde sicher noch weniger gehen aber so ist das ausreichend.
    Irgendwie führt das doch das ganze Threading ad absurdum, wenn du die ganze Zeit auf ein Control (Listview) zugreifst. Ich gehe davon aus, dass du per Invoke die ganze Zeit in den GUI-Thread rüberhüpfst.
    Ein besseres Konzept wäre vielleicht Databinding zu benutzen.

    Das gibt dann wahrscheinlich auch Probleme, wenn man die Datenquelle in nem anderen Thread bearbeitet. Allerdings könnte man es ja so designen, dass man erst eine Kopie der Datenquelle in dem Nebenthread bearbeitet.
    Dabei sollte dann während der ganzen Zeit das Listview für den Nutzer ReadOnly sein.
    Einfach auf den User schieben? WTF? Was kann der User dafür?
    Das einzige was mir schlampig erscheint, ist irgendwo ein 50 ms sleep reinzuquetschen.

    Das Erstellen des Inhalts kann ja vom eigentlichen Befüllen des Listviews abgekoppelt werden.
    Sprich erst in nem anderen Thread ne Datasource befüllen. Dann Datasource an Listview neubinden. Nur der letzte Schritt muss im GUI-Thread erfolgen.
    Der User ist immer Schuld, was macht der auch Sachen die Softwareseitig nicht vorgesehen sind. ^^

    Das die Daten dort angezeigt werden muss schon zeitnahe passieren, so das mir ein füllen alle 2sek z.B., eigentlich zu lange wäre.
    Und wenn ich dann meinetwegen im Sekunden Takt die angelaufenen Daten eintragen lasse, ist der Thread damit auch erstmal blockiert.

    Im Normalfall werden in diesem Abschnitt zwischen 0 und ca. 100 Items generiert, es gibt da aber auch spezielle User die bekommt da auch schon mal weit mehr wie 5000 hin.
    Für diese Usergruppe habe ich diese spezielle Funktion schon abwählbar gemacht, so das es in Zukunft eine absolute Ausnahme bleiben sollte.

    Und für diese eigentlich unscheinbare und nebensächliche Funktion viel Zeit zu investieren,
    für eine Lösung die Codeseitig vielleicht etwas sauberer ist aber am Ende keine nennenswerten Vorteile bringt, fällt bei meiner Kosten-Nutzen-Rechnung einfach durch.
    imo braucht man keinen Code-Ausschnitt, weil wurde ja schon gesagt: Ein Thread, der Massen-Operationen auf Controls ausführt (wie etwa ListView-Befüllung) ist absurd, weil er per Invoking sich selbst und auch das Gui permanent ausbremst. Da ist ohne Threading performanter, weil grad Invoking kostet.
    Das muss neu konzipiert werden.

    Erster Versuch: Verwende mal ListView.BeginUpdate, um die permanente Bildschirm-Aktualiseirung während der Massen-OP zu deaktivieren.
    Meist wirds dadurch so schnell, dass auf Threading ganz verzichtet wern kann.
    Ich frage nach Code, da der TE sagt, er schreibt pro Schleifendurchlauf fortlaufend in die ListView. Das ist schon mal ein grober Fehler. Sammelt er jedoch pro Schleifendurchlauf die ListViewItems in einer Liste und fügt am Ende des Druchlaufs die Items gesammelt per .AddRange() hinzu, so bleibt die GUI durchaus bedienbar. Getestet mit 1000 Items pro Sekunde auf einem sehr langsamen NetBook. In Verbindung mit .BeginUpdate, .EndUpdate ist das Problem sicherlich in den Griff zu bekommen. Nur das Invoke in der Schleife frisst natürlich den GUI-Thread. Hier kann man auch Überlegen, ob Threading überhaupt nötig ist.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    Dieser extra Thread läuft nicht alleine für die besagte Aktion und soll sicherstellen das die Form bedienbar bleibt so lange der Prozess läuft.
    Der Codeabschnitt der die Listview füllt ist nur ein sehr kleiner und nebensächlicher Teil des Threads, der erstens nur optional läuft und zweitens einen Anteil von <5% ausmacht und im Normalfall eine Laufzeit von 0 bis 3sek hat.

    Ihr habt sicher recht das man das optimaler gestallten könnte, aber für meinen Zweck ist das erst mal ausreichend so.