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: { }
}
}
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
In folgender zeile tritt ein fehler auf (InvalidOperationException):
if(rest==2)textBox2.Text+="2";
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.
Herzliche Grüße
Lars
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?
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
Wenn ich jede zeile, in der textbox2.Text=.. steht in eine eigene methode schreibe, dann habe ich doch aber 11 funktionen hinterher. 🙁
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
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
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.
Hallo winSharp93,
das das an dieser Stelle recht wenig sinn macht ist klar, das solte eher ein allgemeiner Tip sein
Herzliche Grüße
Lars
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: { }
}
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.