tutorials.de Buch-Aktion 05/2012
Like Tree1Danke
  • 1 Beitrag von napstermania
ERLEDIGT
NEIN
ANTWORTEN
10
ZUGRIFFE
1121
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    DexXxtrin DexXxtrin ist offline Mitglied Gold
    Registriert seit
    Aug 2007
    Ort
    Luzern CH
    Beiträge
    207
    Hallo zusammen

    Ich habe ein kleines Problem:
    Bei meinem Programm erstelle ich eine Thread, indem das ganze Programm ablauft (Grund: Enthält "endlosschleife")
    Nun mit dem Thread können ja nur static typen verwendet werden.
    Wenn ich jetzt bei meiner Form z.B ein Label einfüge ist dieses Element ja nicht statisch. Ich habe dann im Form.Designer.cs den Code abgeändert. (this weg und public static anstatt private)
    Aber das VisualStudio 2008 macht diesen Vorgan immer Rückgängig, bzw. überschreibt die änderung wieder sobald ich eine Änderung vornehme...

    Wie kann ich das lösen, damit ich die Steuerelemente(ComPort, Label, ImageBox,...) auch im Thread benutzen kann?

    Vielen Dank

    DexXxtrin
     

  2. #2
    Masterclavat Masterclavat ist offline Mitglied Brokat
    Registriert seit
    Oct 2007
    Beiträge
    325
    Du kannst auf ein Steuerelement per Invoke aus einem Hintergrundthread zugreifen.
    Geändert von Masterclavat (16.02.10 um 22:18 Uhr)
     

  3. #3
    napstermania napstermania ist offline Mitglied Silber
    Registriert seit
    Jul 2004
    Ort
    Deutschland
    Beiträge
    95
    Hallo,

    das klingt für mich als würdest du alles (funktionalität, Threads etc.) in deiner abgeleiteten Form Klasse implementieren.
    Ich würde dir raten die Logik und die Oberfläche voneinander zu trennen. (Google -stichwort: "MVC oder MVVM pattern")
    In deiner Oberfläche kannst du dann entsprechende Events platzieren und deine Logischen Klassen können sich an diesen Events anmelden. Das ganze per Invoke abarbeiten, damit du auch Threadübergreifend arbeiten kannst. Wenn man sich daran hält hat man am ende die wenigsten Probleme was das aktualisieren der Oberfläche angeht.

    Gruß
     

  4. #4
    DexXxtrin DexXxtrin ist offline Mitglied Gold
    Registriert seit
    Aug 2007
    Ort
    Luzern CH
    Beiträge
    207
    Danke schon mal für eure Hilfe.

    Nun habe ich noch eine Frage zu Invoke:
    kann ich nur Funktionen per Invoke aufrufen oder auch direkt das Steuerelement?
    Irgendwie werde ich nicht schlau über die genaue und richtige Verwendung.
    Habe mal anhand dieses Beispiels versucht: http://marioschneider.blogspot.com/2...ltithread.html
     

  5. #5
    DexXxtrin DexXxtrin ist offline Mitglied Gold
    Registriert seit
    Aug 2007
    Ort
    Luzern CH
    Beiträge
    207
    Ich habe das jetzt mal so gelöst. Kann man das so mache, bzw. ist dies eine saubere Variante? (Form wie ich auf das Objekt zugreiffe (Label1))

    Code csharp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
        public partial class Main
        {
                ...
                Thread main = new Work().InitializeWork(this);
                main.start();
        }
     
        public class Work
        {
            private SchlScan myForm;
     
            public Thread InitializeWork(SchlScan myform)
            {
                this.myForm = myform;
                return new Thread(new ThreadStart(this.ReceivedLoop));
            }
     
            public void ReceivedLoop()
            {
                myForm.Label1.Text = "Test";
            }
         }
     

  6. #6
    Avatar von Shakie
    Shakie Shakie ist offline Mitglied Diamant
    Registriert seit
    May 2004
    Ort
    Europa
    Beiträge
    2.048
    Was meinst du mit "das Steuerelement aufrufen"?
     
    hihi = -h²

  7. #7
    DexXxtrin DexXxtrin ist offline Mitglied Gold
    Registriert seit
    Aug 2007
    Ort
    Luzern CH
    Beiträge
    207
    Also einfach deinem Label, Textbos, ImageBox, usw. eine Eigenschaft ändern oder einen Wert setzen.
     

  8. #8
    napstermania napstermania ist offline Mitglied Silber
    Registriert seit
    Jul 2004
    Ort
    Deutschland
    Beiträge
    95
    Hallo,

    das funktioniert zwar, allerdings ist es keine saubere Variante, da du eine direkte Abhängigkeit von deiner Form in der Worker Klasse erzeugst. Wenn du es so machen will dann benutze ein Interface der Form um eine saubere Trennung zu gewährleisten.
    Ich habe mal ein kleines Beispiel wie ich es lösen würde. Ist sicherlich keine Musterlösung oder ein muss aber vielleicht hilft es etwas. Ich habe das Beispiel von deinem Link etwas abgeändert.

    Form Class.
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    
    public partial class MainForm : Form
        {
            MathClass _mathClass = null;
     
            public MainForm()
            {
                InitializeComponent();
     
                this._mathClass = new MathClass();
                this._mathClass.NotifyUICall += new UpdateUI(NotifyUICall);
            }
     
            public void NotifyUICall(int number, int val)
            {
                object o = new object();
                lock(o)
                {
                    try
                    {
                        if (this.InvokeRequired == false)
                        {
                            this.richTextBox_Output.AppendText(string.Format("thread {0} has done {1} % of its job\n", number, val));
                        }
                        else
                        {
                            this.Invoke(new UpdateUI(NotifyUICall), number, val);
                        }
                    }
                    catch (System.Exception e)
                    {
                        MessageBox.Show(e.Message);
                    }                
                }            
            }
     
            private void button_Run_Click(object sender, EventArgs e)
            {
                 _mathClass.Initialize(1);
                 _mathClass.Initialize(2);
            }
        }

    Math Class:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    class MathClass
        {
            public event UpdateUI NotifyUICall;
     
            public void Initialize(int number)
            {
                Thread t = new Thread(new ParameterizedThreadStart(this.CalcBackground));
                t.Start(number);
            }
     
            public void CalcBackground(object number)
            {
                int num = (int)number;
                if(NotifyUICall != null)
                {
                    for (int i = 0; i <= 100; i++)
                    {
                        NotifyUICall(num, i);
                    }
                }            
            }
        }

    In den Namespace kommt der delegat, damit der von überall aus erreichbar ist.

    Code :
    1
    
    public delegate void UpdateUI(int number, int val);
     

  9. #9
    DexXxtrin DexXxtrin ist offline Mitglied Gold
    Registriert seit
    Aug 2007
    Ort
    Luzern CH
    Beiträge
    207
    Demfall verstehe ich das doch richtig so:
    Ich muss für jede Änderung eine Funktion in der Main-Klasse schreiben, auf die ich dan zugreiffe.
    Das heisst ich muss eine Funktion haben, wenn ich den Text eines Labels ändern will, eine Andere wenn ich ein Bild in einer ImageBox laden will...
     

  10. #10
    napstermania napstermania ist offline Mitglied Silber
    Registriert seit
    Jul 2004
    Ort
    Deutschland
    Beiträge
    95
    Das kommt immer ganz darauf an was du machen willst. Wenn du den Namen des Bildes in einem Label ausgeben und zeitgleich das Bild anzeigen möchtest, kannst du das auch in einer Methode implementieren. In der NotifyUICall Methode hast du ja kompetten Zugriff auf alle Steuerelemente der Klasse MainForm. Wenn du allerdings Bildanzeige und Labelausgabe von unterschiedlichen Stellen aus setzt dann wäre es ratsam das ganze zu trennen.
    DexXxtrin bedankt sich. 

  11. #11
    DexXxtrin DexXxtrin ist offline Mitglied Gold
    Registriert seit
    Aug 2007
    Ort
    Luzern CH
    Beiträge
    207
    Ok. Vielen Dank für die Hilfe. Funktioniert tiptop.
     

Ähnliche Themen

  1. Antworten: 7
    Letzter Beitrag: 10.06.10, 23:16
  2. Antworten: 5
    Letzter Beitrag: 30.09.08, 16:22
  3. Drupal static page mit unterseiten, alle auf die static page verweisend
    Von flokli im Forum Content Management Systeme (CMS)
    Antworten: 0
    Letzter Beitrag: 07.06.08, 21:04
  4. Frage zu static und static const
    Von Xebov im Forum C/C++
    Antworten: 5
    Letzter Beitrag: 12.07.05, 09:38
  5. Antworten: 8
    Letzter Beitrag: 25.05.04, 15:31

Stichworte