Deaktivert Konto Skrevet 12. desember 2010 Del Skrevet 12. desember 2010 Hei! Har laget et lite program, men støter på noen leifer.. Her er koden: KODE FØR AKTUELL FUNKSJON using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace PrimeI { public partial class Form1 : Form { public Form1() { InitializeComponent(); label6.Text = ""; } private void DoIt_Click(object sender, EventArgs e) { if (bulks.Checked == true) { label1.Text = ""; label2.Text = ""; string start = startingAt.Text; string number = NumberOf.Text; startingAt.Text = "Calculating..."; NumberOf.Text = "This might take a while..."; string[] enter = { start, number, bulksSize.Text, bulksNumber.Text }; string location = CalcBulks(enter); startingAt.Text = "Finished calculating."; NumberOf.Text = "The primes are located in:"; label6.Text = location; } else { if (checkBox1.Checked != true) { label1.Text = ""; label2.Text = ""; string start = startingAt.Text; string number = NumberOf.Text; startingAt.Text = "Calculating..."; NumberOf.Text = "This might take a while..."; string[] enter = { start, number }; string location = Calc(enter); startingAt.Text = "Finished calculating."; NumberOf.Text = "The primes are located in:"; label6.Text = location; } else { label1.Text = ""; label2.Text = ""; string start = startingAt.Text; string number = NumberOf.Text; startingAt.Text = "Calculating..."; NumberOf.Text = "This might take a while..."; string[] enter = { start, number }; string location = CalcOne(enter); startingAt.Text = "Finished calculating."; NumberOf.Text = "The primes are located in:"; label6.Text = location; } } this.Close(); } private string Calc(string[] startNumber) { uint primeCount = 0; string path = @"C:\primeresult.txt"; System.IO.StreamWriter mySW = new System.IO.StreamWriter(path, false); double primeEnter = Convert.ToDouble(startNumber[0]) - 1; int numberOfPrimes = Convert.ToInt32(startNumber[1]); //numberOfPrimes = antall programmet skal finne. if (primeEnter + 1 <= 3) { [size="5"][b]mySW.WriteLine("2");[/b][/size] mySW.WriteLine("3"); primeEnter = 4; primeCount += 2; } bool tester = false; //Hvis tester = true så er det et primtall. for (ushort i = 0; primeEnter < numberOfPrimes; i++) //egentlig hele programmet her. Det repeteres til du finner "numberOfPrimes" primtall. { while (tester == false) //mens det ikke er et primtall { primeEnter++; //legg til én og prøv igjen. Dette er grunnen for at jeg la til (-1) i linje 17. tester = IsPrime(primeEnter); //denne returnerer true hvis den finner at det er et primtall } if (primeEnter <= numberOfPrimes) { mySW.WriteLine(primeEnter); primeCount++; } tester = false; //stiller tilbake boolen. } mySW.WriteLine(); mySW.WriteLine(); mySW.WriteLine("TOTAL NUMBER OF PRIME NUMBERS CALCULATED: " + primeCount); mySW.Dispose(); mySW.Close(); return path; } private string CalcOne(string[] startNumber) { uint primeCount = 0; string path = @"C:\primeresult.txt"; System.IO.StreamWriter mySW = new System.IO.StreamWriter(path, false); double primeEnter = Convert.ToDouble(startNumber[0]); int numberOfPrimes = Convert.ToInt32(startNumber[1]); //numberOfPrimes = antall programmet skal finne. if (primeEnter <= 3) { mySW.WriteLine("2"); mySW.WriteLine("3"); primeEnter = 4; primeCount += 2; } primeEnter -= 1; bool tester = false; //Hvis tester = true så er det et primtall. for (ushort i = 0; primeCount < numberOfPrimes; i++) //egentlig hele programmet her. Det repeteres til du finner "numberOfPrimes" primtall. { while (tester == false) //mens det ikke er et primtall { primeEnter++; //legg til én og prøv igjen. Dette er grunnen for at jeg la til (-1) i linje 17. tester = IsPrime(primeEnter); //denne returnerer true hvis den finner at det er et primtall } if (primeCount <= numberOfPrimes) { mySW.WriteLine(primeEnter); primeCount++; } tester = false; //stiller tilbake boolen. } mySW.WriteLine(); mySW.WriteLine(); mySW.WriteLine("TOTAL NUMBER OF PRIME NUMBERS CALCULATED: " + primeCount); mySW.Dispose(); mySW.Close(); return path; } AKTUELL FUNKSJON private string CalcBulks(string[] startNumber) { int bulkNumber = (Convert.ToInt32(startNumber[3])); int bulksCount = 0; int bulkSize = Convert.ToInt32(startNumber[2]); while(bulksCount < bulkNumber) { string path = @"C:\PrimeResultBulksOf" + startNumber[2] + @"BulkNumber" + Convert.ToString(bulksCount + 1) + ".txt"; uint primeCount = 0; System.IO.StreamWriter mySW = new System.IO.StreamWriter(path); double primeEnter = Convert.ToDouble(startNumber[0]); //numberOfPrimes = antall programmet skal finne. if (primeEnter <= 3) { mySW.WriteLine("2"); mySW.WriteLine("3"); primeEnter = 4; primeCount += 2; } primeEnter -= 1; bool tester = false; //Hvis tester = true så er det et primtall. for (ushort i = 0; primeCount < bulkNumber; i++) //egentlig hele programmet her. Det repeteres til du finner "numberOfPrimes" primtall. { while (tester == false) //mens det ikke er et primtall { primeEnter++; //legg til én og prøv igjen. Dette er grunnen for at jeg la til (-1) i linje 17. tester = IsPrime(primeEnter); //denne returnerer true hvis den finner at det er et primtall } if (primeCount <= bulkNumber) { mySW.WriteLine(primeEnter); primeCount++; } tester = false; //stiller tilbake boolen. bulksCount++; mySW.WriteLine(); mySW.WriteLine(); mySW.WriteLine("TOTAL NUMBER OF PRIME NUMBERS CALCULATED: " + primeCount); mySW.Dispose(); mySW.Close(); } } return @"C:\PrimeResult(...) files"; } KODE ETTER AKTUELL FUNKSJON static bool IsPrime (double primeTester) { uint squareRt = Convert.ToUInt32(Math.Ceiling(Math.Sqrt(primeTester))); uint i = 2; //denne skal primeTester deles på. Om det kommer ut at den deles uten noen desimalplasser, finner programmet ut at det ikke er et primtall. while (i <= squareRt) //hvis i er større enn squareRt er i et primtall. { if (primeTester % i == 0) //altså, primeTester er ikke et primtall { return false; } i++; //ellers legger man til 1 og prøver igjen. } return true; } private void checkBox1_CheckedChanged(object sender, EventArgs e) { if (bulks.Checked != true) { if (checkBox1.Text == "Number of primes instead") { checkBox1.Text = "Last number to check instead"; label2.Text = "Enter number of primes to check:"; } else { checkBox1.Text = "Number of primes instead"; label2.Text = " Enter last number to check:"; } } } private void bulks_CheckedChanged(object sender, EventArgs e) { if (bulks.Checked == true) { checkBox1.Text = "Number of primes (LOCKED)"; label2.Text = "Enter number of primes to check:"; NumberOf.Text = "DON'T USE THIS BOX"; } else { if (checkBox1.Checked == true) { NumberOf.Text = ""; checkBox1.Text = "Last number to check instead"; label2.Text = "Enter number of primes to check:"; } else { NumberOf.Text = ""; checkBox1.Text = "Number of primes instead"; label2.Text = " Enter last number to check:"; } } } } } Får feilen "ObjectDisposedException was unhandled," "Cannot write to a closed TextWriter." Noen som vet hva jeg har gjort galt? Lenke til kommentar
OleM80 Skrevet 12. desember 2010 Del Skrevet 12. desember 2010 Forsøk å bytte om disse 2 linjene: mySW.Dispose(); mySW.Close(); Sett close først. Lenke til kommentar
MailMan13 Skrevet 12. desember 2010 Del Skrevet 12. desember 2010 (endret) Du sier ikke hvor det skjer, men det ser ut som det er frdi du lukker StreamWriter'en din inni en løkke i CalcBulks. Neste iterasjon som prøver å skrive til den etter den er lukket feiler. Det er ikke nødvendig å kalle både Dispose() og Close() heller, Dispose vil rydde opp og lukke for deg, det er det den er til. Close() etter Dispose() vil ikke gjøre noe som helst. Det finnes også en egen konstruksjon i C# som er designet akkurat for å unngå problemet du har her. Using-nøkkelordet tar en variabel/deklarasjon og sørger for at Dispose() kjøres automatisk på den når kontrollen forlater blokken, uansett hvordan det skjer. Da er du garantert at den blir lukket, at den bare lukkes når koden inni blokken er ferdig og variablenen som deklareres er kun i scope innenfor using-blokken, slik at det er umulig å skrive til den etter den er lukket. using(var writer = new StreamWriter(...)) { .... kode som skriver } // automatisk dispose I ditt tilfelle ville jeg også injisert strømmen inn CalcBulks-metoden din, slik at du holder detaljene rundt hva det skrives til, og livssyklus-ting adskilt fra det som skjer i metoden. private string CalcBulks(string[] startNumber, StreamWriter outStream) { ... // ingen instansiering eller close/dispose her } // Så i koden som kaller using(var outStream = new StreamWriter(...)) { CalcBulks(... , outStream) } Uansett hvordan du gjør det, ikke kall close/dispose manuelt. Bruk using-konstruksjonen, så forsvinner denne problematikken av seg selv. Endret 12. desember 2010 av MailMan13 Lenke til kommentar
Deaktivert Konto Skrevet 12. desember 2010 Forfatter Del Skrevet 12. desember 2010 (endret) Takker mye for kommentarene. Prøver tester med using {} nå. @mailman, i eksempel 2, hvorfor kaller du using etter slutten av metoden? Skal den ikke være inni? I.e.: private void metode() { int i = 0; while (i < 12) { using (var sw = new System.IO.StreamWriter(@"C:\fil.txt") { sw.WriteLine(i); } } } Endret 12. desember 2010 av DarkLightA Lenke til kommentar
Deaktivert Konto Skrevet 12. desember 2010 Forfatter Del Skrevet 12. desember 2010 Tror jammen at det kan være at programmet funker nå! Men jeg må vente litt, bruker det akkuratt nå til å kalkulere de første 25.000.000 primtallene.. Er på 11.000.000 nå Kjekt med programmering synes jeg, men jeg har ikke funnet en god tutorial ennå. Vet dere om noen? --- Og jeg beklager at jeg ikke spesifiserte hvilken linje jeg hadde problemer med. Jeg trodde jeg gjorde det, men noe må ha skjedd. Det var i linjen: System.IO.StreamWriter mySW = new System.IO.StreamWriter(path); Lenke til kommentar
MailMan13 Skrevet 12. desember 2010 Del Skrevet 12. desember 2010 Den skal stå inni en metode ja, jeg er bare lat og gadd ikke skrive en hel metodedeklarasjon å putte den i. Meningen var at using og variabeldeklarasjonen burde stå utenfor "CalcBulks", slik at den ikke trenger å bry seg om hva den skriver til. Det er ikke direkte relatert til feilen din, men det er ofte lurt å ikke gi for mye ansvar til hvert element i programmet ditt. Opprette og lukke en fil er ikke relatert til å regne primtall, så da gir det også mening å ikke ha det på samme sted i koden. http://en.wikipedia.org/wiki/Separation_of_concerns Lenke til kommentar
Deaktivert Konto Skrevet 12. desember 2010 Forfatter Del Skrevet 12. desember 2010 (endret) Ja, jeg vet. Dette er den første applikasjonen min, men jeg skal ha det i tankene i fremtiden. Vil dette da fungere? private void metodeEn() { int i = 32; metodeTo(i); } private void metodeTo(int a) { using (var mySW = new System.IO.StreamWriter(@"C:\Output\Fil.txt") { mySW.WriteLine(a); } } Hvordan kan jeg lage en tredje metode som representerer det som skal være inni 'using'? Endret 12. desember 2010 av DarkLightA Lenke til kommentar
Deaktivert Konto Skrevet 12. desember 2010 Forfatter Del Skrevet 12. desember 2010 Idé-dump: private void metodeEn() { string[] beskjed = new string[] {"Hei.", "Brukernavnet", "Mitt", "Er", "DarkLightA."} foreach (string i in beskjed) { metodeTo(i); } } private void metodeTo(int a) { using (var mySW = new System.IO.StreamWriter(@"C:\Output\Fil.txt") { var[] swAndInputVar = new var[] { mySW, a }; metodeTre(swAndInputVar); } } private void metodeTre(var[] inputVariables) { inputVariables[0].WriteLine(inputVariables[1]); } Eller går jeg for langt i metode tre? Lenke til kommentar
GeirGrusom Skrevet 12. desember 2010 Del Skrevet 12. desember 2010 Hva er poenget med disse funksjonene? Du bare lager en funksjon som gjør livet vanskeligere for deg selv. Og hvorfor åpner og lukker du filene stadig vekk? Lenke til kommentar
Deaktivert Konto Skrevet 12. desember 2010 Forfatter Del Skrevet 12. desember 2010 Nei, dette var bare et forsøk på å bruke flere enn én funksjon før det blir mer komplisert.. Lenke til kommentar
GeirGrusom Skrevet 12. desember 2010 Del Skrevet 12. desember 2010 Ah ok Vel var[] er ikke lov. Var brukes utelukkende til å deklarere variabler der datatypen blir tatt ut av sammenheng. Lenke til kommentar
Deaktivert Konto Skrevet 12. desember 2010 Forfatter Del Skrevet 12. desember 2010 Ok. Er det sa noen måte å bruke en annen funksjon inni 'using'? Lenke til kommentar
GeirGrusom Skrevet 12. desember 2010 Del Skrevet 12. desember 2010 Ja. Bare tenk at objektet inne i using([objekt]) er kun gylding innenfor blokken. På slutten blir Dispose() kalt på objektet. using oversettes til dette: { var mySW = new System.IO.StreamWriter(@"C:\Output\Fil.txt"); try { // kode... } finally { mySW.Dispose(); } } Så du kan gjøre hva du vil innenfor using blokken. Lenke til kommentar
Manfred Skrevet 30. desember 2010 Del Skrevet 30. desember 2010 Det kan også da legges til at using kan kun brukes på objekter som implementerer IDisposable. Lenke til kommentar
Degeim Skrevet 4. januar 2011 Del Skrevet 4. januar 2011 Manfred er tilbake på forumet! Det var lenge siden, det. Lenke til kommentar
GeirGrusom Skrevet 6. januar 2011 Del Skrevet 6. januar 2011 (endret) Sant Velkommen tilbake, din rabbagast! Endret 6. januar 2011 av GeirGrusom Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå