Laden...

Mein Programm wird ganz grau

Erstellt von llot a mi vor 14 Jahren Letzter Beitrag vor 14 Jahren 1.278 Views
L
llot a mi Themenstarter:in
5 Beiträge seit 2009
vor 14 Jahren
Mein Programm wird ganz grau

Ich habe ein Programm geschriben, das alle Primzahlen von 1 bis n ausgibt. (ok- ich habe mich von Beispielcode in C inspirieren lassen).

Wenn ich In textbox1 eine zahl größer 10000 Eingebe, wird das programm ganz grau und braucht einfach ewig. Wie kann ich das verhindern?

Außerdem würde ich gerne einen Fortschrittsbalken als popup machen, bekomme es aber nicht ganz hin (neues formular mit ner prograssBar drauf erstellt habe ich):


public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            int m = 0;
            foreach (char c in textBox1.Text)
            {
                m = m * 10;
                if (c == '0') m += 0;
                if (c == '1') m += 1;
                if (c == '2') m += 2;
                if (c == '3') m += 3;
                if (c == '4') m += 4;
                if (c == '5') m += 5;
                if (c == '6') m += 6;
                if (c == '7') m += 7;
                if (c == '8') m += 8;
                if (c == '9') m += 9;
            }
            //new Form2().progressBar1.Maximum=m; geht irgendwie nicht
            textBox2.Text = "";
            bool[] notPrimzahl=new bool[m];
            PrimEndlichGefunden(2, notPrimzahl);
        }

        private void PrimEndlichGefunden(int p, bool[] notPrimzahl)
        {
            int dec=10;
            while(dec<p)
            {
                dec*=10;
            }
            int rest=p;
            while(dec>1)
            {
                rest=p%dec;
                dec/=10;
                rest -= rest % dec;
                rest /= dec;
                if(rest==0)textBox2.Text+="0";
                if(rest==1)textBox2.Text+="1";
                if(rest==2)textBox2.Text+="2";
                if(rest==3)textBox2.Text+="3";
                if(rest==4)textBox2.Text+="4";
                if(rest==5)textBox2.Text+="5";
                if(rest==6)textBox2.Text+="6";
                if(rest==7)textBox2.Text+="7";
                if(rest==8)textBox2.Text+="8";
                if(rest==9)textBox2.Text+="9";
            }
            textBox2.Text+="\r\n";
            for (int i = p; i < notPrimzahl.Length; i += p)
            {
                notPrimzahl[i] = true;
            }
            while (p < notPrimzahl.Length)
            {
                if(notPrimzahl[p]!=true)
                {
                    goto gefunden;
                }
                p++;
            }
            goto end;
        gefunden:
            PrimEndlichGefunden(p, notPrimzahl);
        end: { }
        }
    }

5.742 Beiträge seit 2007
vor 14 Jahren

Hallo llot a mi,

herzlich willkommen hier auf myCSharp.de!

klarer Fall für [FAQ] Warum blockiert mein GUI? - du braucht einen weiteren Thread.

Ansonsten siehe auch [Artikel] Performant Strings verketten

L
llot a mi Themenstarter:in
5 Beiträge seit 2009
vor 14 Jahren

In folgender zeile tritt ein fehler auf (InvalidOperationException):


               if(rest==2)textBox2.Text+="2";
2.223 Beiträge seit 2005
vor 14 Jahren

Hallo llot a mi und auch von mir ein Herzliches Willkommen,

die Antwort brauch ich ja nicht mehr geben,

jedoch da du hier im Forum neu bist, muss ich dich auf etwas aufmerksam machen.

  1. zur besseren Lesbarkeit habe wir recht schöne C# Code Tags
  2. Versuche bitte nächstes mal, dein geposteten Code auf mögliche Problemfälle zu filtern.

Herzliche Grüße
Lars

L
llot a mi Themenstarter:in
5 Beiträge seit 2009
vor 14 Jahren

ok, aber durch das new Thread dings bekomm ich mehr Fehler (Ich hatte den code endlich fehlerfrei 🙁 ), als beseitigt werden. Gibts nicht noch was einfacheres als dieses new Thread?

2.223 Beiträge seit 2005
vor 14 Jahren

Du darfst ja auch nicht nicht aus einem Threads heraus auf GUI elemente zugreifen

du mußt das ganze 'Invoken'

aber das sollte, unter den dir gegebenen Links auch stehen

ein kleiner Tipp noch am Rande:
zu deinen


if (..)
if (..)
if (..)

schau Dir mal die Thematik Switch Case an
http://openbook.galileocomputing.de/csharp/kap12.htm
Herzliche Grüße
Lars

L
llot a mi Themenstarter:in
5 Beiträge seit 2009
vor 14 Jahren

Wenn ich jede zeile, in der textbox2.Text=.. steht in eine eigene methode schreibe, dann habe ich doch aber 11 funktionen hinterher. 🙁

2.223 Beiträge seit 2005
vor 14 Jahren

Nein das hättest du nicht, wenn du einmal über Kapslung nachdenkst

also gleichen Code in eine Methode rein und diese Methode mit Parametern aufrufen
zb



public void AddNumber(int number){
    textbox1.Text += number;
}


Herzliche Grüße
LArs

2.223 Beiträge seit 2005
vor 14 Jahren

mal eine andere Frage warum machst du
sowas


                if (c == '0') m += 0;
                if (c == '1') m += 1;
                if (c == '2') m += 2;
                if (c == '3') m += 3;
                if (c == '4') m += 4;
                if (c == '5') m += 5;
                if (c == '6') m += 6;
                if (c == '7') m += 7;
                if (c == '8') m += 8;
                if (c == '9') m += 9;

oder auch dein anderern If Block?
und nicht einfach


                 m += int.Parse(c.ToString());

Herzliche Frage
Lars

5.742 Beiträge seit 2007
vor 14 Jahren

also gleichen Code in eine Methode rein und diese Methode mit Parametern aufrufen

Hmm - es wäre fast besser, die Textbox nicht andauernd zu aktualisieren. Dann bringt der zweite Thread eher nichts mehr.
Entweder eine Aktualisierung am Ende des Vorganges, eine Aktualisierung alle n Primzahlen oder eine alle x Sekunden via Timer.

oder auch dein anderern If Block? und nicht einfach

Bzw: Gleich:


m = Int32.Parse(textbox.1.Text)

Besser wäre natürlich noch ein TryParse zum Abfangen von Fehleingaben.

2.223 Beiträge seit 2005
vor 14 Jahren

Hallo winSharp93,

das das an dieser Stelle recht wenig sinn macht ist klar, das solte eher ein allgemeiner Tip sein

Herzliche Grüße
Lars

L
llot a mi Themenstarter:in
5 Beiträge seit 2009
vor 14 Jahren

Da das mit dem Thread nich so will (ohne parameter geht das mit invoke, mit parameter nicht), Habe ich mir mal winSharp93´s 2. Tutorial angeschaut und es klappt!!
Jetzt graus das Programm nichtmehr aus und ist viiielll schneller, sogar, wenn ich 100.000 eingebe.
Bei 1.000.000 bekomme ich aber eine StackOverfow-Exception!

danke @ winSharp93

Ein Fortschrittsbalken und keine Exception mehr, dann ist das Prog fertig.


        private void button1_Click(object sender, EventArgs e)
        {
            //new Thread(DoSomethingExpensive).Start(); Fehler: InvalidOperationException bei DoCheapGuiAccess
            DoSomethingExpensive();
        }

        private void DoSomethingExpensive()
        {
            int m = Int32.Parse(textBox1.Text);
            //Form2 form2=new Form2();
            //form2.progressBar1.Maximum=m; geht irgendwie nicht
            //Application.Run(form2); invalid Operation exception
            textBox2.Text = "";
            bool[] notPrimzahl = new bool[m];
            StringBuilder primzahlStringBuilder = new StringBuilder();
            PrimEndlichGefunden(2, notPrimzahl,primzahlStringBuilder);
            //this.Invoke(new MethodInvoker(DoCheapGuiAccess(primzahlStringBuilder.ToString()))); Fehler: Methodenname Erwartet
            DoCheapGuiAccess(primzahlStringBuilder.ToString());
        }

        private void DoCheapGuiAccess(string text)
        {
            textBox2.Text = text;
        }
        
        private void PrimEndlichGefunden(int p, bool[] notPrimzahl,StringBuilder primzahlStringBuilder)
        {
            primzahlStringBuilder.Append(p);
            primzahlStringBuilder.AppendLine();
            for (int i = p; i < notPrimzahl.Length; i += p)
            {
                notPrimzahl[i] = true;
            }
            while (p < notPrimzahl.Length)
            {
                if (notPrimzahl[p] != true)
                {
                    goto gefunden;
                }
                p++;
            }
            goto end;
        gefunden:
            PrimEndlichGefunden(p, notPrimzahl,primzahlStringBuilder);
        end: { }
        }
J
237 Beiträge seit 2008
vor 14 Jahren

Goto ist ganz böse. Immer vermeiden!
Ich hätte das ganze mit dem BackgroundWorker gemacht:


private void startBtn_Click(object sender, EventArgs e) {
    startBtn.Enabled = false;
    bgw.RunWorkerAsync((int) maxNumberUpDwn.Value);
}

private void bgw_DoWork(object sender, DoWorkEventArgs e) {
    int max = (int)e.Argument;
    StringBuilder sb = new StringBuilder();
    for(int i = 1; i <= max; ++i) {
        if(IsPrime(i)) // IsPrime muss noch implementiert werden
            sb.AppendLine(i.ToString());
    }
    e.Result = sb.ToString();
}

private void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
    resultTextBox.Text += (string)e.Result;
    startBtn.Enabled = true;
}

Die ProgressBar ist über ProgressChanged schnell eingebaut.

Grüße, JasonDelife.

Beim Programmieren löst man die Probleme, die man nicht hätte, programmierte man nicht.