Autor Beitrag
braincom654
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 32



BeitragVerfasst: Fr 20.07.12 00:34 
Hallo Community,

bei meinem Programm gibt es folgendes Problem:

In einem neuen Thread soll es einfach in der Oberfläche etwas ändern, hier der Code:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
     MethodInvoker otherInvoke = delegate
            {
                progressBar.Visible = true;
                progressBar.BringToFront();
            };
            MethodInvoker myINvoker = delegate
            {
                panelBackgroundBlack.Visible = true;
                panelBackgroundBlack.BackColor = Color.FromArgb(50000);
            };
            Invoke(myINvoker);
            Invoke(otherInvoke);

Jedoch bleibt es schon beim ersten Invoke hängen und zwar bis...

Kurz noch etwas anderes, während dieser Thread hier läuft geht das Programm weiter jedoch ist das mein einziger Thread.

...das Programm die anderen Zeilen Code ausgeführt hat.
Was ist das Problem hier? Sollte ich den anderen Code auch in einem neuen Thread laufen lassen?

Wäre sehr dankbar wenn mir jemand weiterhelfen könnte.

edit:
Habe erst jetzt gesehen, dass dieser Beitrag besser in WinForm untergebracht wäre. Jedoch glaube ich habe ich nicht die Befügnis mein Thema zu verschieben, oder habs einfach nicht gefunden. :D

Moderiert von user profile iconNarses: C#-Tags hinzugefügt
Moderiert von user profile iconNarses: Topic aus Sonstiges (.NET) verschoben am Fr 20.07.2012 um 09:13
daeve
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 116
Erhaltene Danke: 3

Windows (XP Pro, 7 Ultimate x64)
C#,WPF,Java,ASP.Net, VS 2010 Ultimate (x86)
BeitragVerfasst: So 22.07.12 13:09 
willst du den eine ProgressBar aneigen lassen ?

msdn.microsoft.com/e...221403(v=vs.95).aspx Erklärt den Backgroundworker in c#

dieser linkt sollte das ganze gut erklären.

Jedenfalls wenn ich den Problem richtig verstanden habe..
braincom654 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 32



BeitragVerfasst: So 22.07.12 18:32 
user profile icondaeve hat folgendes geschrieben Zum zitierten Posting springen:
willst du den eine ProgressBar aneigen lassen ?

msdn.microsoft.com/e...221403(v=vs.95).aspx Erklärt den Backgroundworker in c#

dieser linkt sollte das ganze gut erklären.

Jedenfalls wenn ich den Problem richtig verstanden habe..


Hallo daeve,

danke für die Antwort, jetzt klappt es zwar einigermaßen jedoch nicht so wie ich mir vorgestellt habe.

Das ganze Programmm hängt es trotzdem schön auf, am ersten Aufruf ohne Backgroundworker braucht es vielleicht 5 Sekunden. Jedoch mit den Bgw braucht es 20 Sekunden und mehr. Doch ich glaube da müsste ich hier fast das ganze Programm höchstwahrscheinlich uploaden, weil nur aus schnipsel versteht man zu wenig.
Wenn einer wirklich so nett sein sollte und mir dabei helfen möchte und sich die mühe machen will, kann sich gerne melden.

Aber danke für deine Antwort daeve :)
daeve
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 116
Erhaltene Danke: 3

Windows (XP Pro, 7 Ultimate x64)
C#,WPF,Java,ASP.Net, VS 2010 Ultimate (x86)
BeitragVerfasst: So 22.07.12 22:39 
weist du denn wo in deinem Code sich das Programm aufhängt ?

kannst das ganze doch debuggen mit breakpoints.. bis du herausfindest wo das Problem ist.

Dann kann dir ev. weitergeholfen werden.
braincom654 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 32



BeitragVerfasst: Mo 23.07.12 01:33 
Ich vermute einfach das er zuviel Arbeiten muss in Taskmanger steigt der Arbeitsspeicher immer über 500.000 rauf und ich denke das ist ziemlich viel für diesen Programm. Denn es liest ein paar IP's aus der Console aus und gibt den ungefähren Standort dieser IP zurück mithilfe eines xml API.
Ich habe herausgefunden dass das Programm einfach richtig langsam wird. Zb. beim debuggen wenn ich F11 drücken will, um die nächste Zeile zu debuggen braucht der manchmal schon das zu verarbeiten.
Hier mal eine zusammenfassung was so parallel läuft, also nicht jede variable aber halt so längere schleifen usw.

Also ich öffne hier meine ersten 2 Threads:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
Thread main = new Thread(new ThreadStart(mainCode));
            main.Start();

            Thread gui = new Thread(new ThreadStart(changeGUI));
            gui.Start();



1.Thread main

ausblenden C#-Quelltext
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:
while (true)
            {
                zahl = newText.IndexOf("TCP"3);
                if (zahl == -1) { zahl = newText.IndexOf("UDP"3); }
                if (zahl == -1) { break; }

                lines[i] = newText.Substring(0, zahl);


                zahl = newText.IndexOf("TCP"3);
                if (zahl == -1) { zahl = newText.IndexOf("UDP"3); }
                if (zahl == -1) { break; }

                newText = newText.Substring(zahl);
                i++;
            }
            Array.Resize(ref lines, i);
            if (!start)
            {
                myCommandOutput = new CommandOuput(lines);
                start = true;
            }
            else
            {
                myCommandOutput.setMoreZeilen(lines);
            }
            guiStart = true;


2. Thread gui

ausblenden volle Höhe C#-Quelltext
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:
MethodInvoker invok = delegate
            {
                while (!guiStart)
                {

                }
                listViewFirst.Items.Clear();

                foreach (Zeile item in myCommandOutput.getZeilen())
                {
                    ListViewItem zuAdden = new ListViewItem(item.protokoll);
                    zuAdden.SubItems.Add(item.localEndPoint.ToString());
                    zuAdden.SubItems.Add(item.remoteEndPoint.ToString());
                    zuAdden.SubItems.Add(item.status);
                    zuAdden.SubItems.Add(item.countrFullName);

                    if (item.oldStatus == "old")
                    {
                        zuAdden.BackColor = Color.OrangeRed;
                    }
                    else if (item.oldStatus == "new")
                    {
                        zuAdden.BackColor = Color.LightGreen;
                    }

                    listViewFirst.Items.Add(zuAdden);
                }
                if (myCommandOutput.firstRound)
                {
                    myCommandOutput.firstRound = false;
                }

                lblAnzahl.Text = myCommandOutput.getZeilen().Count + " found";
                myCommandOutput.zeilenListe.Clear();
            };
            Invoke(invok);
            guiStart = false;


Hier die wichtigsten Informationen aus der Klasse CommandOutput:

ausblenden volle Höhe C#-Quelltext
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:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
public void setMoreZeilen(string[] text)
        {
            this.prozent = 0;
            foreach (string item in text)
            {
                string neu = item.Replace(" "";");
                addZeile(neu);
            }
            getLocation();

            this.howMany = permZeilenListe.Count;
        }
  public void addZeile(string zeiel)
        {
            string copyZeile = zeiel;
            int zahl = -1;

            string proto = zeiel.Substring(03);

            zahl = zeiel.IndexOfAny(numbers);
            int zahl2 = zeiel.IndexOf(":");
            zahl2 -= zahl;
            try
            {
                localIp = IPAddress.Parse(zeiel.Substring(zahl, zahl2));
                copyZeile = zeiel.Substring(zahl2);
                zahl = copyZeile.IndexOf(";");
                zahl2 = copyZeile.IndexOf(":");
                string test = copyZeile.Substring(zahl2 + 1, zahl);
                local = new IPEndPoint(localIp, Convert.ToInt32(copyZeile.Substring(zahl2 + 1, zahl - zahl2 - 1)));

                copyZeile = copyZeile.Substring(zahl);
                zahl = copyZeile.IndexOfAny(numbers);
                copyZeile = copyZeile.Substring(zahl);


                zahl = copyZeile.IndexOf(":");
                IPAddress remoteIp = IPAddress.Parse(copyZeile.Substring(0, zahl));
                copyZeile = copyZeile.Substring(zahl);

                zahl = copyZeile.IndexOf(";");
                IPEndPoint remoteEndPoint = new IPEndPoint(remoteIp, Convert.ToInt32(copyZeile.Substring(1, zahl - 1)));
                copyZeile = copyZeile.Substring(zahl);

                zahl = copyZeile.IndexOfAny(chars);
                copyZeile = copyZeile.Substring(zahl);
                zahl = copyZeile.IndexOf(";");

                string status = copyZeile.Substring(0, zahl);

                Zeile newZeile = new Zeile(proto, status, local, remoteEndPoint);

                zeilenListe.Add(newZeile);
                this.prozent += 1;
            }
            catch (Exception) { }
        }

  public void getLocation()
        {
            try
            {
                this.schritte = (100 - prozent) / howMany;
            }
            catch (Exception)
            {
                this.schritte = 100;
            }
            foreach (Zeile item in zeilenListe)
            {
                try
                {
                    string website = "XXXXXXX";

                    WebClient wClient = new WebClient();
                    string strSource = wClient.DownloadString(website + item.remoteEndPoint.Address.ToString());
                    int numb = strSource.IndexOf(";");
                    strSource = strSource.Substring(numb);

                    numb = strSource.IndexOfAny(chars);
                    strSource = strSource.Substring(numb);
                    numb = strSource.IndexOf(";");
                    item.countryCode = strSource.Substring(0, numb);
                    strSource = strSource.Substring(numb);
                    numb = strSource.IndexOfAny(chars);
                    strSource = strSource.Substring(numb);
                    numb = strSource.IndexOf(";");
                    item.countrFullName = strSource.Substring(0, numb);

                    try
                    {
                        search = permZeilenListe.Find(test => test.localEndPoint.ToString() == item.localEndPoint.ToString() && test.remoteEndPoint.ToString() == item.remoteEndPoint.ToString());
                    }
                    catch (Exception) { }

                    if (!permZeilenListe.Contains(search))
                    {
                        neue = new Zeile(item);
                        neue.oldStatus = "new";
                        permZeilenListe.Add(neue);
                    }
                    else
                    {
                        neue = new Zeile(search);
                        permZeilenListe.Remove(search);
                        neue.oldStatus = "old";
                        permZeilenListe.Add(neue);
                    }
                }
                catch (Exception)
                {
                    item.countryCode = "404: NOT FOUND";
                    item.countrFullName = "404: NOT FOUND";
                }

                prozent += schritte;
            }
            prozent = 100;
            Thread.Sleep(100);
            prozent = 0;
        }


Die Zeile Klasse, ist einfach nur eine Klasse die einige Properies hat aber sonst eigentliche keine Methoden.

Vor diesen 2 Thread lass ich noch den BackgroundWorker arbeite:

ausblenden volle Höhe C#-Quelltext
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:
private void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            zeit = 0;
            count = false;
            Thread countIT = new Thread(new ThreadStart(myTimerLOL));
            countIT.Start();

            int bevor = prozent;
            int value = (int)e.Argument;

            while (true)
            {
                if (value == 100)
                {
                    worker.CancelAsync();
                    break;
                }

                prozent = Convert.ToInt32(myCommandOutput.prozent);

                if (prozent != bevor)
                {
                    if (prozent <= 100)
                    {
                        value = prozent;
                        bevor = prozent;
                    }
                    else
                    {
                        value = 100;
                    }
                }
                worker.ReportProgress(value);
            }
        }


Hier wird noch diese Methode aufgerufen, die verwende ich jedoch nur um den ganzen vorgang zu zählen. Ist alles fertig geladen wird dem User auch mitgeteilt wie lange es gedauert hat, hatte vorher einen Timer jedoch klappte das mit dem nicht der war auch wie eingefroren. Hier noch die Methode:


ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
public void myTimerLOL()
        {
            while (!count)
            {
                zeit += 0.1;
                Thread.Sleep(100);
            }
        }


Das wäre so ziemlich alles was nebnenbei läuft. Grundsätzlich wollte ich einfach ein progressbar einbauen, der eingezeigt wird während es die IP's ausliest und located. Jedoch hängt das ziemlich und der Progressbar wird erst so nach 5 Sekunden angezeigt und danach ladet er kaum und plötzlich ist er voll. Dies alles wird bei einem button_click event aufgerufen und danach ist die Form eigentlich wie eingefroren. Doch ich verstehe nicht warum, läuft ja alles in einen eigenen Thread und der Progressbar in einem Bgw.
Hoffe ihr versteht was ich meine ;D
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4799
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mo 23.07.12 12:33 
Hallo braincom654,

mir erscheint dein ganzes Vorgehen falsch zu sein, denn du hast einige grundlegende Fehler, wie man mit Threads arbeitet:
- warum so viele (händische) Threads?
- du läßt einige deiner Threads (bzw. die BackgroundWorker.DoWork-Methode) ohne Pause (Thread.Sleep) laufen -> hohe CPU-Auslastung (!!!)
- Threadsynchronisation über boolsche Variablen - insbesondere mit der CPU belastenden Schleife while (!guiStart) { }: stattdessen sollte man die Klassen ManualResetEvent bzw. AutoResetEvent benutzen.

Der Vorschlag von daeve, den BackgroundWorker zu benutzen, war insbesondere dazu gedacht, die Threads komplett rauszuwerfen. Stattdessen hast du noch einen (unnötigen) Thread mehr erzeugt :think:

Und für die Berechnung der vergangenen Zeit gibt es die Stopwatch-Klasse.

Ab .NET 4 sollte man (wenn man nicht sowieso den BackgroundWorker benutzt), die Task Parallel Library (TPL) (mit dessen Task-Klasse) verwenden.

Für diesen Beitrag haben gedankt: braincom654
braincom654 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 32



BeitragVerfasst: Di 24.07.12 16:54 
Dachte ich mir irgendwie auch schon das es in die Richtung läuft.

Habe jetzt alles umstrukturiert und auch die Stopwatch Klasse verwendet, echt hilfreich. Nun funktioniert es auch wie gewollt, die Form wird nicht eingefroren und der Progressbar wird schön geladen. Vielen dank ;D