Threading anwenden

  • C#

Es gibt 27 Antworten in diesem Thema. Der letzte Beitrag () ist von pferdefleisch.

    Threading anwenden

    Hi Leute,

    ich bin momentan an einem Projekt drann, wo ich merke das ich langsam ohne Threading nicht auskommen werde. Ich denke das ich das Thema Threading verstanden habe, aber ich weiss leider nicht wie ich das an meinem Fall sinvoll anwenden kann. Code ist in C#. Bitte verschieben sollte es nicht hier reinpassen.

    Ich habe zwei Methoden.
    Die erste Methode macht nicht anderes als über php informationen zu holen. Dient also nur zur Aktualisieren von Informationen im Programm.

    Die zweite Methode hingegen bezieht sich nur auf das aktualisieren der Controls. Sprich, ich starte Methode eins - hole mir also den aktuellsten Stand ausm www. Anschließend möchte ich den neuen Stand in meinen Controls anzeigen.

    Das momentane Problem ist, dass das durchlaufen der Methode zwei einfach zu lange dauert und somit die ganze Form blockiert. Methode eins habe ich bereits in einem Thread ausgelagert und läuft recht fix durch. Nur muss ich auch drauf achten das Methode eins durchgelaufen sein muss bevor ich die zweite aufrufe.

    So und jetzt zur Frage. Wie kann ich die zweite Methode so aufrufen das sie performant durchgelaufen wird ohne das die Form einfriert?

    Hier noch bisschen code...

    C#-Quellcode

    1. private void btnAktualisieren_Click(object sender, EventArgs e)
    2. {
    3. //Alles aktualisieren
    4. Thread tAkt = new Thread(new ThreadStart(timerAktualisieren));
    5. tAkt.Start();
    6. layoutLaden();
    7. }
    8. //Methode eins
    9. private void timerAktualisieren()
    10. {
    11. benutzer.GetProfil();
    12. benutzer.GetClan();
    13. benutzer.GetTeams();
    14. benutzer.GetShoutbox();
    15. benutzer.GetMitglieder();
    16. }
    17. // Methode zwei
    18. private void layoutLaden()
    19. {
    20. layoutAdmin();
    21. layoutBNachrichtenLaden();
    22. // Header
    23. lblBenutzername.Text = benutzer.benutzer_name;
    24. lblLetzterLogin.Text = "Letzer login war am " + benutzer.benutzer_login.ToString("dd.MM.yyyy HH:mm:ss");
    25. lblStartseiteLetzterLogin.Text = "war am " + benutzer.benutzer_login.ToString("dd.MM.yyyy");
    26. lblStartseiteNachrichten.Text = (gridClanNachrichten.Rows.Count +
    27. gridMeineNachrichten.Rows.Count).ToString() + " Nachrichten";
    28. lblRegistriertSeit.Text = "Seit " + benutzer.benutzer_registrierung.ToString("dd.MM.yyyy") + " registriert";
    29. picAvatar.BackgroundImage = benutzer.benutzer_avatar;
    30. lblClanname.Text = benutzer.clan_name + " [" + benutzer.clan_kuerzel + "]";
    31. lblZuletztAktualisiert.Text = "Zuletzt aktualisiert um " + DateTime.Now.ToString("HH:mm:ss")+" Uhr";
    32. lblVersion.Text = "v"+Application.ProductVersion.ToString();
    33. [.....]
    34. }

    Thread verschoben

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „FlashTek“ ()

    Hy Kassor versuch es mal so

    VB.NET-Quellcode

    1. Dim t as new System.Threading.Thread(new System.Threading.ThreadStart(addressOf layoutLaden))
    2. t.start()


    oder in C#

    C#-Quellcode

    1. System.Threading.Thread t = new System.Threading.Thread(delegate() { layoutLaden(); });
    2. t.Start();
    Meine Projekte Genesis Game Engine | GFX | smartli.me - Der smarte URL shortener

    @Andy16823: Scheint mir falsch, zumindest der C#-Code. Probier ihn mal aus und schau dann, ob der funktioniert.

    C#-Quellcode

    1. new System.Threading.Thread(layoutLaden).Start()
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Trade“ ()

    Echt Na ja ok, dann entschuldige ich mich. Ich teste es nachher mal, kann sein, dass ich mich jetzt irre.

    Edit:// @Andy16823: Jo, es lag nicht am Block, sondern daran, dass ich normal die Kurzform benutze, aber du hast recht, das erwartet dort nen Delegaten, funktioniert also.
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Trade“ ()

    Habe es versucht, leider schmeißt er mir dann diesen Fehler:

    Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement lblZuletztAktualisiert erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde.
    Du musst invoken.

    C#-Quellcode

    1. Invoke(new Action(() =>
    2. {
    3. // Code hier rein
    4. }));


    @Andy16823: CheckForIllegalCrossThreadCalls ist böse.
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    Einfacher ist aber nicht immer besser. Somit behebst du das Problem nicht, du versteckst es nur. Es ist also absolut nicht im Sinne eines guten Programmes es zu nutzen. Es dient nur zur Debugassistenz, für fertige Programme absolut ungeeignet.
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    Ich habs jetzt mal invoked. Fehler treten keine mehr auf, nur anscheinend lädt das layout schon obwohl der erste Thread noch nicht ganz fertig ist die aktuellen informationen einzuholen.
    Auch das 3sekündliche einfrieren ist immer noch da. Vermutlich werden in der layoutladen() Methode einfach zu viele Controls auf einmal aktualisiert. Also somit ist das nutzen des Threads sinnlos. Hmmm...
    starte das laden in deiner timerAktualisieren methode

    C#-Quellcode

    1. private void btnAktualisieren_Click(object sender, EventArgs e)
    2. {
    3. //Alles aktualisieren
    4. System.Threading.Thread t = new System.Threading.Thread(delegate() { timerAktualisieren(); });
    5. t.Start();
    6. }
    7. //Methode eins
    8. private void timerAktualisieren()
    9. {
    10. benutzer.GetProfil();
    11. benutzer.GetClan();
    12. benutzer.GetTeams();
    13. benutzer.GetShoutbox();
    14. benutzer.GetMitglieder();
    15. layoutLaden();
    16. }
    17. // Methode zwei
    18. private void layoutLaden()
    19. {
    20. layoutAdmin();
    21. layoutBNachrichtenLaden();
    22. // Header
    23. lblBenutzername.Text = benutzer.benutzer_name;
    24. lblLetzterLogin.Text = "Letzer login war am " + benutzer.benutzer_login.ToString("dd.MM.yyyy HH:mm:ss");
    25. lblStartseiteLetzterLogin.Text = "war am " + benutzer.benutzer_login.ToString("dd.MM.yyyy");
    26. lblStartseiteNachrichten.Text = (gridClanNachrichten.Rows.Count +
    27. gridMeineNachrichten.Rows.Count).ToString() + " Nachrichten";
    28. lblRegistriertSeit.Text = "Seit " + benutzer.benutzer_registrierung.ToString("dd.MM.yyyy") + " registriert";
    29. picAvatar.BackgroundImage = benutzer.benutzer_avatar;
    30. lblClanname.Text = benutzer.clan_name + " [" + benutzer.clan_kuerzel + "]";
    31. lblZuletztAktualisiert.Text = "Zuletzt aktualisiert um " + DateTime.Now.ToString("HH:mm:ss")+" Uhr";
    32. lblVersion.Text = "v"+Application.ProductVersion.ToString();
    33. [.....]
    34. }
    Meine Projekte Genesis Game Engine | GFX | smartli.me - Der smarte URL shortener

    dann solltest du deine Methode nochmals überdenken ...
    eine Möglichkeit wäre zB. mit Bindings zu arbeiten und das GUI besser zu strukturieren.
    Danke euch vielmals. Es läuft schon um einiges besser. Der Freeze ist leider nicht vollständig weg, vermutlich weil es einfach zu viele Controls auf einmal sind die aktualisiert werden müssen. Leider weiss ich auch nicht wie ich das umstrukturieren könnte. Naja aber bis dahin danke :)
    Das wird so, wie du dir das vorstellst, nicht funktionieren. Bei allem, was mit Controls zu tun hat, musst du zwingend im Hauptthread arbeiten. Egal was du machst, du wirst immer damit enden, dass du das Zeug zurück in den Hauptthread invokest, und deswegen bringt dir der Thread dann überhaupt nichts. Du kannst nur diejenigen Sachen verlagern, bei denen auf keine Controls zugegriffen wird, mehr geht einfach nicht.
    Hi,

    du müsstest dir evtl eine neue GUI-Struktur ausdenken und das Ganze evtl. überdenken. Brauchst du bestimmte Sachen? Würden sie sich besser lösen lassen? Gehe das nochmal durch und schau, ob du etwas findest.

    Grüße Trade
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!: