Threading mit Invoke sub?

  • C#

Es gibt 21 Antworten in diesem Thema. Der letzte Beitrag () ist von BeefyX.

    Threading mit Invoke sub?

    hallo com;

    ich abrbeite gerade mit c# und threads.
    nun habe ich das problem das ich vom thread aus keine anweisung zu einer checkbox machen kann.

    bei vb kenn ich es mit Invoke(sub()

    aber bei c# weis ich nicht wie das geht und ich habe nichts gesehen was für mich das selbe zu erscheinen vermag.

    könnte mir einer eventuel sagen wie das ich dies lösen könnte?

    hier ein kleiner aussschnitt.

    fehler:
    Fehler 1 Für das nicht statische Feld, die Methode oder die Eigenschaft "WindowsFormsApplication1.Form1.checkBox3" ist ein Objektverweis erforderlich. C:\Users\******\documents\visual studio 2012\Projects\WindowsFormsApplication1\WindowsFormsApplication1\Form1.cs 70 9 WindowsFormsApplication1



    VB.NET-Quellcode

    1. public static void normalxml()
    2. {
    3. try
    4. {
    5. CheckForIllegalCrossThreadCalls = false;
    6. XmlDocument doc = new XmlDocument();
    7. doc.Load("test.xml");
    8. XmlElement root = doc.DocumentElement;
    9. if (checkBox3.Checked == true)
    Lass Dir mal diesen Text vom Konverter nach C# übersetzen:

    VB.NET-Quellcode

    1. Me.Invoke(Sub() Me.TextBox1.Text = "bla")
    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!

    RodFromGermany schrieb:

    Lass Dir mal diesen Text vom Konverter nach C# übersetzen:

    VB.NET-Quellcode

    1. Me.Invoke(Sub() Me.TextBox1.Text = "bla")


    dies ergibt

    VB.NET-Quellcode

    1. this.Invoke(() => this.TextBox1.Text == "bla")


    VB.NET-Quellcode

    1. if (this.Invoke(() => this.checkBox3.Checked) == true)


    doch das this wird nicht akzeptiert. das ist ja das problem, ich weis nicht wie ich es in einer If anweisung angeben soll =)

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

    Fein. Klar, dass das falsch ist, aber jetzt hast Du einen Anhaltspunkt, wie das in C# aussehen könnte. Google mal nach Lambda-Ausdrücken.
    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!
    Editiere mal nicht den darüberstehenden Post.
    Invoke brauchst Du, um Control-Properties zu verändern, Abfragen geht ohne Invoke.
    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!
    okay, ich frage mich nur, warum gerade das invoke so anderst ist als VB,
    ich komme gerade nicht ganz klar in c# mit invoke. habe es laut google und anderen forn mal so geschriben, leider auch ohne erfolg.

    VB.NET-Quellcode

    1. checkBox3.Invoke( new MethodInvoker(() => {
    2. if (checkBox3.Checked == true)
    3. {
    4. gbname = "1";
    5. }
    6. else
    7. {
    8. gbname = "2";
    9. }
    10. }));
    habe gerade herausgefunden das dass Problem nur dann kommt wen ich anstatt

    VB.NET-Quellcode

    1. public void xml()



    VB.NET-Quellcode

    1. public static void xml()
    mache...

    das Problem kommt wegen dem Static. aber dies muss ich machen wen ich mit Threads arbeiten möchte, oder irre ich mich da?

    mfg

    und vielen dank für eure Hilfe.!
    Statische Klassen müssen und können nicht instanziiert werden, es sei denn, sie enthalten nicht-statische Methoden und Klassen. Wird die Klasse instanziiert, stehen dann aber auch nur diese nicht-statischen Funktionen zur Verfügung.

    Deshalb kannst du das "this"-Schlüsselwort, das ja bekanntlich auf die aktuelle Instanz verweißt, logischerweise nicht in statischen Klassen nutzen.


    Kleine Beispielklasse

    Quellcode

    1. static class DownloadClass
    2. {
    3. string _path;
    4. public static byte[] DownloadFileFromStatic(string Path)
    5. {
    6. //Hier könnte ihre Werbung stehen
    7. }
    8. public byte[] DownloadFileFromInstance()
    9. {
    10. //Hier könnte ihre Werbung stehen
    11. }
    12. public DownloadClass(string Path)
    13. {
    14. //So sehen Initializer in c# aus.
    15. _path = Path;
    16. }
    17. }


    Quellcode

    1. DownloadClass.DownloadFileFromStatic("http://idontcare.com/shtfck.txt"); //geht klar
    2. DownloadClass.DownloadFileFromInstance(); //geht nicht, da nicht aus Instanz ausgerufen
    3. DownloadClass downloader = new DownloadClass("http://idontcare.com/shtfck.txt");
    4. downloader.DownloadFileFromInstance(); // geht
    5. downloader.DownloadFileFromStatic("http://idontcare.com/shtfck.txt") //geht nicht, da statische Methode von Instanz aufgerufen




    In instanziierten Klassen kannst du Threadübergreifende Control-Zugriffe dann genau so realisieren, wie Fire88 es geschrieben hat, oder aber statt der anonymen Methode einfach einen Methodennamen angeben.

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „creac“ ()

    Hallo leute, ich habe mein vorriges Programm anderst gelöst. nun möchte ich es aber wirklich lernen wie es geht. doch auf msdn werde ich nicht schlau.. (leider)

    daher störe ich euch nun noch ein mal.

    ich habe hier ein ganz kleines Beispiel welches ich mit Invoke lösen muss, da es sonst die werte nicht in die TextBox schreiben kann.

    VB.NET-Quellcode

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.Threading.Tasks;
    6. using System.Windows;
    7. using System.Windows.Controls;
    8. using System.Windows.Data;
    9. using System.Windows.Documents;
    10. using System.Windows.Input;
    11. using System.Windows.Media;
    12. using System.Windows.Media.Imaging;
    13. using System.Windows.Navigation;
    14. using System.Windows.Shapes;
    15. using System.Threading;
    16. using System.Threading.Tasks;
    17. namespace WpfApplication1
    18. {
    19. /// <summary>
    20. /// Interaktionslogik für MainWindow.xaml
    21. /// </summary>
    22. public partial class MainWindow : Window
    23. {
    24. public MainWindow()
    25. {
    26. InitializeComponent();
    27. }
    28. public void btn_start_Click(object sender, RoutedEventArgs e)
    29. {
    30. Thread t1 = new Thread(new ThreadStart(left));
    31. t1.Start();
    32. }
    33. public void left()
    34. {
    35. for (int i = 0; i < 50; i++)
    36. {
    37. tbleft.Text = i.ToString();
    38. }
    39. }
    40. }
    41. }


    nun möchte ich euch fragen on mir jemand zu diesem Beispiel eine Invoke schreiben könnte, da ich es sonst nicht schnalle mit den Anweisungen von Msdn.

    Danke

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

    1. inzwischen auf wpf umgestiegen, was? ;) Da gehts mit Dispatcher.Invoke

    2. Wozu zum Kuckuck diese ganzen unnötigen Leerzeilen? Das sieht immer nach viel Code aus, ist aber nur unleserlich.

    3. Bitte machn Beispiel, was kompilieren würde.

      Quellcode

      1. tbleft.Text += 1;
      halte ich für Verarsche

    4. Threading hat so keinen Sinn. Ein Thread soll gefälligst viiiel arbeiten, bevor er Ergebnisse an den Gui-Thread weiterleitet.
      Jede Iteration einen Thread-Übergang zu machen ist kein Threading, sondern etwas schlimmes.
    jap, habe bemerkt das ich ja mit wpf viel besser mit der Form arbeiten kann =)


    welche vielen Leerzeichen? ich habe es direkt aus VS 2012RC kopiert.


    tbleft ist eine Textbox =)

    oder was meinst du genau mit verarsche? verstehe ich leider nicht ganz.


    das denke ich auch, nur wollte ich es ja nur als Beispiel haben, das ich daraus lernen kann. dan kann ich es von selbst versuchen so anzuwenden wen ich mal mehr machen muss. deshalb dachte ich mir ich mache etwas kleines simples.

    VB.NET-Quellcode

    1. tbleft.text += 1;
    ergibt keinen Fehler, der Fehler kommt erst nach dem Start da der Thread die werte in einen anderen Thread schreiben möchte.
    daher würde ich gerne die Invoke Methode lernen, die bei Msdn für mich nicht verständlich ist.

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

    C#-Quellcode

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.Windows;
    6. using System.Windows.Controls;
    7. using System.Threading;
    8. namespace WPFChart {
    9. /// <summary>summary für Idioten bitte auch entfernen</summary>
    10. public partial class MainWindow : Window {
    11. public MainWindow() {
    12. InitializeComponent();
    13. }
    14. public void btn_start_Click(object sender, RoutedEventArgs e) {
    15. Thread t1 = new Thread(new ThreadStart(left));
    16. t1.Start();
    17. }
    18. public void left() {
    19. var s = "";
    20. for(int i = 0; i < 50; i++) {
    21. s += i.ToString();
    22. }
    23. this.Dispatcher.BeginInvoke(new Action(() => tbleft.Text = s));
    24. }
    25. public void ohneThread() {
    26. var s = "";
    27. for(int i = 0; i < 50; i++) {
    28. s += i.ToString();
    29. }
    30. tbleft.Text = s;
    31. }
    32. }
    33. }
    Dassisjetzt besonders kompakt, weil ich meine IDE so eingestellt hab, dass öffnende Klammern keine eigene Zeile belegen.
    Vmtl. habe ich doppelt so viel Code auf einen Blick auffm Bildschirm (dassis wichtig für die Lesbarkeit), und wo eine Methode aufhört und die nächste anfängt ist auch klarer erkennbar, als wennman beliebig Leerzeilen einstreut.

    ErfinderDesRades schrieb:

    Dassisjetzt besonders kompakt, weil ich meine IDE so eingestellt hab, dass öffnende Klammern keine eigene Zeile belegen.

    Das ist natürlich eine super Idee, werde das auch mal suchen und so einstellen. Finde auch selbst das dein Code viel geordneter aussieht.

    ErfinderDesRades schrieb:

    Vmtl. habe ich doppelt so viel Code auf einen Blick auffm Bildschirm (dassis wichtig für die Lesbarkeit), und wo eine Methode aufhört und die nächste anfängt ist auch klarer erkennbar, als wenn man beliebig Leerzeilen einstreut.

    Da gebe ich dir Vollkommen recht! =)

    Vielen dank für das Beispiel, nun weis ich endlich wie ich es handhaben muss mit dem Invoke.
    Nur mal so ne Frage..
    Wenn ich das so mache:

    VB.NET-Quellcode

    1. Me.Invoke(Sub()
    2. TestFunction()
    3. End Sub)
    4. '...
    5. Sub TestFunction()
    6. Me.TextBox1.Text = "Test!"
    7. End Sub


    (Me.Invoke... von einem Thread aus aufrufen)
    Gilt dann das Invoke für alles was in der Funktion steht?