1. #1

    Registriert seit
    28.10.2011
    Beiträge
    625
    Thanked 279 Times in 168 Posts

    Unglücklich C# - Enqueue Threads

    Hey!

    Ich möchte einen Loading-Screen erstellen. Dabei wird bei der Loading-Klasse erst die einzelnen Callbacks hinzugefügt und dann das ganze gestartet.


    this.loading = new Loading();

    this.loading.Run("STEAM_PATH", delegate () {
    if (this.steam.IsInstalled()) {
    Logger.Info("Steam is not installed? Ask for Workspace...");
    this.workspace.Show();
    this.loading.Wait();
    return true;
    }

    this.workspace.SetPath(this.steam.GetPath());
    Logger.Info("Steam-Path: " + this.steam.GetPath());
    Logger.Info("Installed: " + (this.steam.IsInstalled() ? "Yes" : "No"));
    return true;
    });

    this.loading.Run("KLEI_GAMES", delegate () {
    this.steam.LoadGame(new DSTC());
    this.steam.LoadGame(new DSTS());
    this.steam.LoadGame(new DSTM());
    return true;
    });

    this.loading.Run("KLEI_MODS", delegate () {
    Logger.Info("Load mods...");
    return true;
    });

    this.loading.Start();


    In der Loading-Klasse wird erst eine Liste mit den Callbacks definiert:

    private List<KeyValuePair<String, Func<Boolean>>> workers = new List<KeyValuePair<String, Func<Boolean>>>();


    Und die Run-Methode fügt wie oben die Daten halt in der Liste hinzu:

    public void Run(String name, Func<Boolean> callback) {
    this.workers.Add(new KeyValuePair<String, Func<Boolean>>(name, callback));
    }


    Jetzt kommt hier mein Problem... Die Start-Methode soll nun hingehen und die Liste nacheinander abarbeiten und bei den Callbacks prüfen, ob Beispielsweise das Resultat true ist. Ist es true, ist der Callback normal abgelaufen/durchgeführt und der soll den nächsten in der Liste abarbeiten.

    Ich habe schon mehrere Dinge probiert:
    - Eine Schleife, die das ganze bewerkstelligt und auch IsRunning (gesetzt mit Wait/Resume) berücksichtigt. Problem: Das ganze blockiert (logischerweise) alle GUI-Komponenten
    - Ein extra Thread. Problem: Ich kann keine anderen WPF-Fenster öffnen (z.B. via this.workspace.Show()), da ich eine ThreadException bekomme, weil das ganze sich wohl in einem anderen Thread befindet...

    Dieser ganze Part soll hier ausgeführt werden:

    if (!this.IsRunning() || position >= complete) {
    return;
    }

    ++position;
    var entry = this.workers[position];
    String name = entry.Key;
    Func<Boolean> callback = entry.Value;

    if(!callback()) {
    //this.Wait();
    } else {
    //this.Resume();
    }

    this.SetProgress(position * 100 / complete);

    if (position >= complete) {
    this.SetProgress(100);
    this.callback_success();
    }


    Kann mir jemand helfen, wie ich so eine Queue richtig abarbeiten lasse, sodass ich trotzdem auf andere GUI-Komponenten zugreifen kann und auch die ganze Applikation nicht blockt?

  2. #2
    Avatar von DMW007
    Registriert seit
    15.11.2011
    Beiträge
    6.080
    Thanked 9.118 Times in 2.995 Posts
    Blog Entries
    5

    Standard AW: C# - Enqueue Threads

    Hi,

    mit WPF habe ich zwar noch nie gearbeitet und auch WinForms liegt schon einige Zeit zurück, da ich praktisch nur noch das ASP.NET Core nutze. Grundsätzlich sind WinForms nicht threadsicher. Deinen Tests nach scheint es mit WPF nicht groß anders zu sein. Sobald etwas komplexeres gemacht werden soll, kommt man um Multithreading aber nicht herum. Wird alles im Hauptthread (also dem der GUI) ausgeführt, ist dieser blockiert. Sämtliche Status-Updates (Progressbar, Listeneinträge usw) sind nicht sichtbar. Und für den User hängt die Software. Nicht nur von der Usability her schlecht. Wird der Thread zu lange blockiert, denkt das OS, es hat sich aufgehängt (z.B. Keine Rückmeldung im Titel).

    Um das zu lösen, kannst du mittels Invoke in den UI-Thread springen, und so threadübergreifend auf die Controls zugreifen:

    form.Label.Invoke((MethodInvoker)delegate {
    form.Label.Text = "Abgeschlossen";
    });

    Wird dieser Code in einem separaten Thread ausgeführt, springt er im Delegate quasi in den UI-Thread und ändert den Text des Labels. Jeglicher folgender Code außerhalb wird wieder regulär in dem gesonderten Thread ausgeführt (z.B. Das nächste Element einer Warteschlange irgendwie prozessieren). Ist ein simples Beispiel, welches man natürlich genau so gut mit einer ProgressBar oder jedem anderen UI-Control durchführen kann.

    Eventuell wird in WPF vom Aufbau her anders invoked, das muss ggf. in der Doku nachgeschaut werden. Aber damit hast du mal einen Anhaltspunkt. Ich vermute, das wird dort ähnlich gehandhabt.


Ähnliche Themen

  1. [Kritik] Kritik Threads!
    Von dGL im Forum Feedback
    Antworten: 17
    Letzter Beitrag: 27.02.2013, 19:00
  2. [Vorschlag] Verbieten von Facebook Like Threads
    Von rVs14 im Forum Feedback
    Antworten: 9
    Letzter Beitrag: 04.06.2012, 18:38
  3. [Kritik] Bettel-Threads
    Von CoD im Forum Feedback
    Antworten: 9
    Letzter Beitrag: 14.12.2011, 20:31
  4. [Vorschlag] Threads selber schließen
    Von Tobe im Forum Feedback
    Antworten: 10
    Letzter Beitrag: 04.12.2011, 18:55
Diese Seite nutzt Cookies, um das Nutzererlebnis zu verbessern. Klicken Sie hier, um das Cookie-Tracking zu deaktivieren.