Announcement

Collapse
No announcement yet.

Invoke, nur wie?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Invoke, nur wie?

    Guten Morgen,

    ich habe ein kleines problemchen ich habe einen thread in dem folgendes ausgeführt wird:

    Code:
    public void AutoGet()
    {
    	try
    	{
    	         while(ag == false)
    		{
    			NetworkCredential networkCredential = new NetworkCredential(user,passwd);
    						
    			WebRequest webRequest = WebRequest.Create(url);
    			webRequest.Credentials = networkCredential;
    						
    			WebResponse webResponse = webRequest.GetResponse();
    						
    			Bitmap stream = new Bitmap(webResponse.GetResponseStream());
    			pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
    			pictureBox1.Image = stream;
    					
    			if(checkBox1.Checked == true)
    			{
    				string time = DateTime.Now.ToString("hh_mm_ss");
    				string date = DateTime.Now.ToString("dd_mm_");
    				pictureBox1.Image.Save("save/record"+date+time+".jpg");
    			}
    		}
    				
    	}
    	catch
    	{
    		MessageBox.Show("Falsche Zugangsdaten! Bitte überprüfen!");
    	}
    
    }
    Allerdings friert mein Programm einsobald die checkBox1 markiert wird (speichern tut er die Bilder brav ) und er das Bild speichern soll. Nun habe ich mal ein wenig gelesen und getan und herausgefunden das ich mit sogenannten invokes arbeiten soll. Nun habe ich damit noch nie gearbeitet und frage mich nun wie das genau geht weil ich da echt dran häng

  • #2
    Hallo,

    ein Teil des Code fehlt um das Problem analysieren zu können. ZB woher kommt ag?

    Hinweis:
    Code:
    while(ag == false)
    Sollte nicht verwendet werden. ag ist höchstwahrscheinlich ein Variable des Typ bool und kann somit nur true oder false sein. Eine Prüfung der Art
    Code:
    while (!ag)
    ist besser.

    mfG Gü
    "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

    Comment


    • #3
      Wenn AutoGet in einem anderen Thread läuft also die GUI die du aus der Methode aufrufst dann solltest du eigentlich bereits entsprechende Exceptions bezüglich CrossThread Calls bekommen. Außer du hast die abgeschaltet (ganz böse) oder du benutzt ein Net. Framework mit einer 1 vor dem Dezimaltrenner.

      Unabhängig davon sieht der Code nicht danach aus das das Problem das du zu lösen versuchst für einen threaded Zugriff geeignet ist, insbesondere weil ein Großteil die GUI betrifft. Was spricht dagegen es einfach Single Threaded zu lösen?

      Benutzt du die pictureBox1 nur um das Bild zu stretchen oder willst du es wirklich vor dem speichern anzeigen?

      Comment


      • #4
        Danke für eure Antworten. Ja "ag" ist ein bool....Werde es ändern

        Also "AutoGet" wird als ein Thrad aufgerufen damit die GUI nicht einfriert. Das Problem ist nun nur noch das

        Code:
        if(checkBox1.Checked == true)
        {
        	string time = DateTime.Now.ToString("hh_mm_ss");
        	string date = DateTime.Now.ToString("dd_mm_");
        	pictureBox1.Image.Save("save/record"+date+time+".jpg");
        }
        Dieser Teil arbeitet wahrscheinlich dann nicht mehr in dem Threadbereich sondern im GUI-Thread. (Korregiert mich wenn ich falsch liege )

        Und genau das Problem könnte man doch mit einem invoke lösen oder?
        Wenn ihr andere vielleicht sogar besser Lösungsansätze habt bin ich gern für alles offen

        Liebe Grüße

        Comment


        • #5
          ein Teil des Code fehlt um das Problem analysieren zu können. ZB woher kommt ag?
          Wenn ich nicht weiß woher ag kommt kann ich kein Beispiel erstellen das nicht in einer Endlosschleife endet.

          Zum 1. Code -> du könntest nach dem Speichern Application.DeEvents() aufrufen damit die Anwendung nicht einfriert. Ist einfacher als mit Threads, Delegaten, Invoke zu arbeiten.

          mfG Gü
          "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

          Comment


          • #6
            Enschuldige das hatte ich überlesen. "ag" ist ein Bool der public erstellt wurde und ist standardmäßig auf false. Mit einem button kann ich "ag" auf true setzen um die schleife zu unterbrechen mehr ist das nicht

            Und "Application.DoEvents()" soll klappen? Hmm ich kanns ja mal ausprobieren

            Liebe Grüße

            edit: Wenn ich "AutoGet" nicht in einen Thread packe sondern nur zum Schluss mit Application.DoEvents() abschließe dann friert die GUI solange ein bis das Bild da ist, zeigt es an, und friert wieder ein bis zum nächsten Bild. Irgendwie muss das doch klappen :-) arbeite jetzt mit nem BackgroundWorker und rufe das Asynchron auf. Aber auch keine Chance.

            Als Code auch mal der Aufruf selbst:

            Code:
            private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
            {
                      AutoGet();
            }
            Code:
            public void ToolStripStartPictureClick(object sender, EventArgs e)
            {
                        backgroundWorker1.RunWorkerAsync();
            }
            Zuletzt editiert von J.D.; 06.11.2008, 13:22.

            Comment


            • #7
              Solange du aus dem Thread auf die GUI zugreifst wird sich das nicht ändern auch nicht wenn du synchronisiert (per Invoke) auf die GUI zugreifst, es wird höchstens ein wenig besser.

              Um GUI Thread und Background Thread richtig voneinander zu trennen brauchst du eine Art Man-In-The-Middle Ansatz. Also einen Dritten in der Mitte der vermittelt.

              Ich würde dazu eine sortierte Liste (nach Einfügedatum) der Bilder nehmen.
              Der Thread legt die geholten Bilder in der Liste ab und der Gui Thread entnimmt diese Bilder aus der Liste und zeigt diese an. Damit hast du sauber beide Threads voneinander getrennt und mußt nur die Add und Remove Methoden der Liste mit einem gemeinsamen Lock schützen um Threadsafe zu sein.

              Und du erhälst zusätzlich(so als Bonus ) viele Verbesserungmöglichkeiten für deine Lösung.
              Du könntest z.B. problemlos mehrere Backgroundthreads gleichzeitig Bilder holen lassen oder die Anzeigedauer der Bilder im Gui Thread besser steuern da diese ja nun unabhängig vom Backgroundthread ist.

              Spannende Aufgabe, solltest du selbst mal versuchen, sonst frag nochmal nach wenn du konkretere Hilfe brauchst.

              Comment


              • #8
                Ich würde dazu eine sortierte Liste (nach Einfügedatum) der Bilder nehmen.
                Grober Unfug ... sollte natürlich eine Queue sein und keine sortierte Liste.

                Comment


                • #9
                  oha Dann schau ich mal. Hast du einen konkreten Verweiß auf die Doku damit ich mich einlesen kann?

                  Vielen Dank erst einmal für deine Hilfe..

                  Comment


                  • #10
                    Beschreib mal kurz das Grundproblem (wäre gut wenn das in der 1. Frage von dir getan würde - es könnte ja sein dass der von dir vorgeschlagenen Weg nicht ideal ist sondern es eine besser Alternative gibt):
                    1. von wo sollen die Bilder geholt werden?
                    2. was soll mit den heruntergeladenen Bilder passieren?


                    mfG Gü

                    PS:
                    Code:
                    if(checkBox1.Checked == true)
                    Checked kann nur true/false sein, daher ist eine zusätzliche Prüfung mit == true Schwachsinn.
                    Dies gilt übrigen für alle boolschen Variablen.
                    "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

                    Comment


                    • #11
                      oha Dann schau ich mal. Hast du einen konkreten Verweiß auf die Doku damit ich mich einlesen kann?
                      Eigentlich nicht. Ich weiß allerdings auch nicht für welchen Teil du eine Doku brauchst.

                      Comment


                      • #12
                        Code:
                        public void AutoGet()
                        {
                        	try
                        	{
                                         ag = false;
                        		while(!ag)
                        		{
                        			NetworkCredential networkCredential = new NetworkCredential(user,passwd);
                        						
                        			WebRequest webRequest = WebRequest.Create(url);
                        			webRequest.Credentials = networkCredential;
                        						
                        			WebResponse webResponse = webRequest.GetResponse();
                        				
                        			Bitmap stream = new Bitmap(webResponse.GetResponseStream());
                        			pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
                        			pictureBox1.Image = stream;
                        
                        		}
                        	}
                        	catch
                        	{
                        		MessageBox.Show("FEHLER");
                        	}
                        }
                        So wird das Bild aus dem Internet abgerufen. Es soll dann mit ..Image.Save() in einem Ordner gespeichert werden. Der Obrige Code wird als Thread gestartet damit die GUI nicht einfriert. Das Problem besteht nun darin, dass das Speichern über die GUI-Thread ausgefürht wird und somit das Programm abstürzt.

                        Allerdings habe ich mal eine Idee. Könnte ich beides in jeweiligen backgroundworker stecken und das speichern quasi erst starten wenn der thread zum holen des Bildes vorbei ist? Das müsste doch mit Report klappen oder nicht? So laufen beide threads getrennt voneinander ab. Das müsste doch eigentlich hinhauen

                        Gruß

                        Comment


                        • #13
                          Könnte ich beides in jeweiligen backgroundworker stecken und das speichern quasi erst starten wenn der thread zum holen des Bildes vorbei ist?
                          Somit laufen beide Backgroundworker synchron und sind somit überflüssig. D.h. alles könnte auch in einem Thread laufen.

                          Du kannst die Bilder aus dem Netz in eine Warteschlagen schreiben (wie Ralf schon vorgeschlagen hat) und diese dann von einem 2. Thread verarbeiten lassen.

                          Ob dies sinnvoll ist weiß ich nicht, da das speichern relativ schnell ist - es könnte sein dass der Aufwand zum Verwalten der Queue größer ist als das speichern.

                          mfG Gü
                          "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

                          Comment

                          Working...
                          X