Jump to content
  • 0
Melde dich an, um diesem Inhalt zu folgen  

C# Programmabsturz IO-Exception

Frage

Hallöööchen mit 3 öchen

ich habe ein Programm das Dateien einließt und auch schreibt. Das Programm läuft mit der IDE einwandfrei (liegt auf einem Netzlaufwerk) - ohne IDE stürzt es oft ab.

Unser Netzwerk ist sehr stabil, die exe-Datei, die zu lesende Datei und die zu schreibende Datei befinden sich alle im selben Ordner und sobald ich mein Programm starte passiert es oft das der grüne (Windows 7) Ladebalken in der Pfad-Leiste des Netzwerkordners erscheint, kurz darauf schmeißt mein Programm 2 IO-Exceptions (eine davon "Netzwerkpfad nicht vorhanden") und reagiert schließlich nicht mehr (ich schätze ja das Programm selbst wird komplett in den Arbeitsspeicher geladen sonst kann er ja nicht mehr auf die exe zugreifen?).

Abgefangen habe ich Exceptions so:

try
{ 
...
byte[] response;
	for ()
	{
		while ()
		{
			if ()
			{
				try
				{
				response = WebClient.DownloadData(url)
				}
				catch (WebException)
				{
				Console.WriteLine("HTTP-Error")
				continue;
				}
			}
		}
	}
}
catch (Exception ex)
{
Console.WriteLine(ex);
sw.Close();
sr.Close();
Console.ReadKey();
}
	

Den WebException brauche ich extra, weil das Programm mit neuem Beginn der while-Schleife weiterlaufen muss, bei allem anderen soll es natürlich abbrechen. Ich hätte behauptet eigentlich sollte ich nur 1 Exception erhalten, aber mein Programm wirft ja 2 bevor es abstürzt. Ist das nun weil C# automatisch mehrere Threads erstellt oder rutscht es bei IO-Exceptions irgendwie doch in das kleine WebException rein oder kann ich bei Netzwerkabbruch überhaupt nichts abfangen weil das Programm ja selbst nicht erreichbar ist?

Warum das Netzlaufwerk an erster Stelle da kurz Schluckauf hat weiß ich nicht. Für Hilfe wäre ich wie immer dankbar.

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen

20 Antworten auf diese Frage

Empfohlene Beiträge

  • 0

Irgendwie verstehe ich auch nicht ganz, was du uns mit dem Code mitteilen möchtest. Wie Whizz-zarD schon schrieb ist gar kein WebClient notwendig um Dateien auszulesen bzw zu schreiben.

Könntest du vielleicht den Code vollständig/er posten? Wenn du das nicht öffentlich machen möchtest, kannst du ihn mir auch per PN zukommen lassen, vielleicht kann ich da weiterhelfen.

bearbeitet von Gottlike
typo

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
  • 0

OK dann hier mal anhand des Codes erklärt was ich mache:

try
{ 
...
byte[] response;
//ließ alle Dateien in einem Ordner ein
	for () //für jede Datei führe aus...
	{		//Bsp: skip erste Zeile (Header)
      WebClient wc = new WebClient();
		while ((currentLine = sr.ReadLine()) != null) //für jede Zeile...
		{
			if (!nummerliste.Contains(nummer) 	//wenn eine Nummer in der Datei noch nicht vorkam
			{
              byte[] response = null;
				try
				{
				response = WebClient.DownloadData(url+nummer) //ließ die Seite aus
				}
				catch (WebException)
				{
				Console.WriteLine("HTTP-Error") //Seite gibt bei Stichzeiten einen 500-Error zurück, das ist ein Einzelfall und soll übersprungen werden
				continue;
				}
              //hier noch einige if/Else if/else-Abfragen um die Informationen zu sortieren
              nummerliste.Add(nummer)
			}
		}
        sw.Close();
        sr.Close();
	}
}
catch (Exception ex)
{
Console.WriteLine(ex);
sw.Close();
sr.Close();
Console.ReadKey();
}

Das sollte einen groben EInblick geben was passiert, bzw was ich bezwecken möchte.

Die Betreiber der Siete haben eine API, die aber leider schon seit Wochen in Wartung und nicht verfügbar ist weswegen ich das Programm hier überhaupt schreibe

bearbeitet von Tician

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
  • 0

Soweit ich das verstehe holst du dir noch zusätzliche Daten von einer externen Webseite wofür auch der WebClient genutzt wird?

Die Exceptions werden höchstwahrscheinlich geworfen, weil die URL, die du als Parameter mitgibst, nicht korrekt ist.

Wenn keine Daten vom WebServer geholt werden können, bekommst du auch die IO Exception; weil er nicht weiß was er in die Datei schreiben soll.

Insgesamt ist dein Code aber nicht allzu einfach zu verstehen, vor allem schließt du auch irgendwie mehrfach den StreamWriter, aber die Initialisierung sieht man auch nirgends.

Vielleicht wäre es einfacher wenn du nochmal genau deine Aufgabenstellung bzw. Problemstellung darlegst. Im Ausgangspost hast du nämlich noch nichts vom WebClient bzw. Laden der Daten vom externen Server erwähnt.

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
  • 0

Also willst du ein Webcrawler schreiben?
Warum nimmst du denn nicht einen? z.B. HTTrack?

Die IOException wird auch nicht vom WebClient ausgelöst. Laut Dokumentation werden folgende Exceptions geworfen:

Exception Condition
ArgumentNullException

Der address-Parameter ist null.

WebException

Der URI-Format durch Kombination von BaseAddress und address ist ungültig.

- oder -

Fehler beim Herunterladen von Daten.

NotSupportedException

Die Methode wurde in mehreren Threads gleichzeitig aufgerufen.

Dein Problem muss also beim Lesen oder Schreiben der Dateien zu tun haben. Da dieser Teil in deinem Code fehlt, kann ich dazu nichts sagen. Was genau sagt denn die Exception? Wie sieht denn der Stacktrace aus? Wenn die Symbol-Dateien (*.pdb) dabei liegen, bekommt man sogar die Zeilennummer mit, wo die Exception geworfen worde.

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
  • 0

Ja, mein Programm soll aus csv-Dateien aus jeder Zeile eine bestimmte Spalte auslesen (Zahl). Diese wird an einen link gehängt, der link selbst steht fest im Code und gibt auch ohne den Zusatz der Zahl (oder sogar einer falschen Zahl) ein Ergebnis zurück. Die URL muss richtig sein, zu 99% läuft das Programm durch, selten gibt der angesprochen Server einen Fehler (500 - "Interner Serverfehler") zurück, auch das funktioniert einwadnfrei und das Programm läuft wie ich es wollte weiter.

Der Rest stimmt nicht ganz, ich fächer meinen Code mal komplett auf, aber dadurch das es Spaghetti-Code ist bin ich einfach mittlerweile schon so deprimiert das ich mich nicht mehr traue den Code zu posten ._.

static void Main(string[] args)
        {
            StreamReader sr = null;
            string currentLine;
            StreamWriter sw = null;
            List<string> nummerListe = new List<string>();

            try
            {
                string sourcePath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
                string destinationPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
                  //doppelt da später noch geändert wird
                string[] filearray = Directory.GetFiles(sourcePath, "*.csv");
                int sourcearraylength = filearray.Length;

                if (sourcearraylength == 0) //wenn keine Datei vorhanden dann schließ das Programm
                {
                    Environment.Exit(0);
                }

                for (int x = 1; x <= sourcearraylength; x++) //jeder Datei
                {
                    sr = new StreamReader(filearray[x - 1], true);
                    string dateiname = "\\inArbeit";
                    sw = new StreamWriter(destinationPath + dateiname + ".tmp");
                    WebClient wc = new WebClient();
                  
                    //Read and write header
                    string header = sr.ReadLine();
                    sw.WriteLine(header + ";Status-Text;Status");

                    while ((currentLine = sr.ReadLine()) != null) //jede Zeile
                    {
                        string[] singleData = currentLine.Split(';');
                        string nummer = singleData[6];

                        if (singleData[0] == "Anzahl:")
                        { //Datei hat noch viele leere Zeilen nach "Anzahl:", diese sollen übersprungen  werden
                            sw.WriteLine(currentLine);
                            break;
                        }

                        Console.WriteLine("Schaue nach Nummer: " + nummer);

                        if (!nummerListe.Contains(nummer))
                        {
                            //get site information
                            string url = "https://blabla" + nummer;
                            byte[] response = null;
                            try
                            {
                                response = wc.DownloadData(url);
                            }
                            catch (WebException)
                            {
                                Console.WriteLine("...HTTP-Error");
                                sw.WriteLine(currentLine+";Fehler;Fehler");
                                continue;
                            }                            
                            string webtext = Encoding.ASCII.GetString(response);

                            //Regex for searching
                            Regex reg = new Regex("String1", RegexOptions.Singleline);
                            Regex reg2 = new Regex("String2", RegexOptions.Singleline);
                            Regex reg3 = new Regex("String3", RegexOptions.Singleline);
                            Regex reg4 = new Regex("String4", RegexOptions.Singleline);
                            Match match = reg.Match(webtext);
                            Match match2 = reg2.Match(webtext);
                            Match match3 = reg3.Match(webtext);
                            Match match4 = reg4.Match(webtext);

                            if (match.Success)
                            {

                                sw.WriteLine(currentLine + ";blabla;alles gut");
                                Console.WriteLine("...gut");
                            }
                            else if (match2.Success)
                            {
                                sw.WriteLine(currentLine + ";blabla2;gut");
                                Console.WriteLine("...gut");
                            }
                            else if (match3.Success)
                            {
                                sw.WriteLine(currentLine + ";blabla3;gut");
                                Console.WriteLine("...gut");
                            }
                            else if (match4.Success)
                            {
                                sw.WriteLine(currentLine + ";blabla4;kein Status");
                                Console.WriteLine("...ohne Status");
                            }


                            else
                            {
                                sw.WriteLine(currentLine + ";blabla5;ueberpruefen");
                                Console.WriteLine("...ueberpruefen");
                            }

                            //add to list
                            versandnummerListe.Add(versandnummer);
                        }     
                        else
                        {
                            sw.WriteLine(currentLine + ";bereits geprueft;uebersprungen");
                            Console.WriteLine("...uebersprungen");
                        }  
                                      
                    }
                    sw.Close();
                    sr.Close();

                    File.Move(destinationPath + dateiname + ".tmp", destinationPath + "\\Fertig" + Path.GetFileName(filearray[x - 1]));
                }
                Console.WriteLine("Abgeschlossen\n\nBeliebige Taste zum Beenden des Programmes druecken...");
                Console.ReadKey();
            }          
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                Console.WriteLine("Programm wird beendet, bitte beliebige Taste druecken...");
                sw.Close();
                sr.Close();
                Console.ReadKey();
            }                     
        }

Ich hoffe ich hab alles erwischt was nicht neutral ist.

Wie gesagt das Programm stürzt nur ohne IDE ab und da gibt es dann keine Zeilennummer oder ähnliches, das einzige was ich gesehen habe ist das mehrmals ein "Pfad nicht vorhanden" kam, weil wie gesagt aus irgendeinem Grund beim Programmstart der Netzwerk-Ordner mal kurz neu geladen hat - zum 2. mal.

bearbeitet von Tician

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
  • 0

Und trotzdem hast du nicht meine Frage beantwortet:

vor 38 Minuten schrieb Whiz-zarD:

Was genau sagt denn die Exception? Wie sieht denn der Stacktrace aus? Wenn die Symbol-Dateien (*.pdb) dabei liegen, bekommt man sogar die Zeilennummer mit, wo die Exception geworfen worde.

Aus deinem Code entnehme ich dann, dass die Dateien nicht im Netzwerk-Ordner gelesen und gespeichert werden, sondern im Desktop-Ordner?

Edit:

Fürs lesen und Schreiben von CSV-Dateien gibt es auch fertige Bibliotheken. Da würde ich mir auch nicht mehr die Mühe machen und es selbst implementieren. Den CsvHelper finde ich persönlich nicht schlecht.

bearbeitet von Whiz-zarD

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
  • 0

Oh, ich hatte es jetzt vorübergehend auf Desktop verschoben weil es Netzwerkmäßig eben diesen Hänger hatte, das sollte eigentlich ein Netzwerkpfad sein

                //string sourcePath = @"\\nas-xxx\blabla";
                //string destinationPath = @"\\nas-xxx\blabla";
                string sourcePath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\Ordnername";
                string destinationPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\Ordnername";

So sieht es gerade vorübergehend im Code aus, ich hatte es vergessen zu verändern.

Mit deinen Fragen kann ich nichts anfangen, den genauen Wortlaut der Exceptions muss ich nochmal irgendwie kreieren und hoffen das ich einen Screenshot machen kann und das "Programm funktioniert nicht mehr" blabla von Windows irgendwie wegschieben. Was sind Symbol-Dateien und Stacktrace? Ich kann also die pdb-Datei in den Ordner werfen in dem auch meine exe-Datei ist? Erzeugt das dann eine Datei?

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
  • 0

Die *.pdb-Datei erzeugt keine Datei. Sie dient lediglich dazu, mehr Debug-Informationen zu bekommen. Beispiel:

static void Main(string[] args)
{
    try
    {
        throw new NullReferenceException();
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
    }
    finally
    {
        Console.ReadKey();
    }
}

Wenn ich jetzt das Programm ausführe, erhalte ich folgende Nachricht in der Konsole:

System.NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
   bei ConsoleApplication3.Program.Main(String[] args) in d:\dokumente\visual studio 2015\Projects\ConsoleApplication3\ConsoleApplication3\Program.cs:Zeile 16.

Ich kann also sehen, dass die Exception in Zeile 16 in der Datei Program.cs geworfen wurde und die Zeile ist folgende:

        throw new NullReferenceException();

Auch sollte man die Meldung der Exception verstehen. Die obere Zeile ist die Art der Exception mit einer optionalen Nachricht. Der Teil:

bei ConsoleApplication3.Program.Main(String[] args)

Sagt, wo die Exception ausgelöst wurde und der Teil:

in d:\dokumente\visual studio 2015\Projects\ConsoleApplication3\ConsoleApplication3\Program.cs:Zeile 16.

Ist der Stacktrace. Der Stacktrace kann noch deutlich länger werden, je nach dem wie viele Ebenen der Code absteigt und wieder raufklettern muss, um die Exception zu fangen.

Wenn ich jetzt aber die *.pdb-Datei lösche und das Programm starte, erhalte ich nur folgende Meldung:

System.NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
   bei ConsoleApplication3.Program.Main(String[] args)

Ich sehe also nicht mehr, wo die Exception geworfen wurde, sondern lediglich nur noch die Methode, wo sie ausgelöst wird.

Für dich ist also erst mal der Stacktrace wichtig, um zu wissen, wo überhaupt die Exception aufgetreten ist. Das spart auch schon vieles an Rätselraten. Wenn man die Stelle dann kennt, kann man sich überlegen, was eigentlich passiert ist. Ohne den Stacktrace zu kennen, wird das Debugging sehr schwer.

bearbeitet von Whiz-zarD

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
  • 0

So also ich kann sagen beim ersten Ausführen an jedem PC kommt dieser Fehler, danach nicht mehr. Ich hab also nachdem es 20 mal lief den PC neu gestartet und zack hatte den Fehler. Wie gesagt kann ich nicht sagen warum sich das Netzwerk so verhält, aber das Programm macht komisches, wenn ich das richtig sehe kommt der mit dem sw.Close() nicht klar und schmeißt dann noch einen unbehandelten Fehler?

 

Unbenannt2.png

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
  • 0

Der StreamReader und StreamWriter implementieren auch IDisposable.

Bei solchen Klassen gilt besondere Vorsicht, da man sie im einem using benutzen sollte:

using(StreamWriter writer = new StreamWriter(...))
{
    ...
}

Klassen, die IDisposable implementieren, besitzen sog. unmanaged code. D.h. sie werden vom Gargabe Collector nicht vollständig weggeräumt. Deswegen implementieren solche Klassen einen eigenen Destruktor, um die Ressourcen wieder freizugeben. Per using wird implizit die Dispose()-Methode aufgerufen, die dann die Ressourcen wieder freigibt. Ich vermute mal, dass dort dein Fehler liegt und du auf eine Ressource (sprich auf eine Datei) zugreifen möchtest, die auf der noch ein Handle liegt.

Ich persönlich würde aber nicht so mit Dateien rumhantieren. Ich würde eine geeignete Datenstruktur überlegen und erst mal alles im Speicher machen und dann im letzten Schritt alles als eine Textdatei rauspusten. 

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
  • 0

Ah, dann hast du das wiederholt was mein Ausbilder vorgeschlagen hat: Erst alles in einer Variable sammeln und dann in einem Rutsch in die Datei.

Wenn mein Programm so abstürzt hab ich nämlich auch eine Datei (Die .tmp die geschrieben wird) die sich dann auch nach PC Neustart nicht löschen lässt ("wird von einem Prozess verwendet"), das dauert dann etwa 20 Minuten bis dieser Zugriff weg ist.

Ich habe jetzt oft von managed und unmanaged Code gehört und weiß auch etwa was es ist. Wie erkenne ich unmanaged Code denn, wie kommst du auf dieses IDisposable? Ich dachte unmanaged Code wäre alles was ich von einer .dll entnehme die nicht automatisch in der IDE enthalten ist (z.B. Public Declare Function BlockInput Lib "user32".... ) oder sowas, wir haben das Schreiben und Lesen aus Dateien in der Schule drangenommen aber auch nur ohne dieses "using".

Ich habe also die Wahl entweder erst alles im Speicher zu machen oder ein using zu benutzen. Und wenn ich das richtig gelesen habe dann muss ich Dispose() aufrufen wenn ich fertig bin, aber wenn mein Code gegen die Wand rennt (also ne Exception wirft) dann wird Dispose() automatisch ausgeführt.

https://msdn.microsoft.com/de-de/library/yh598w02.aspx

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
  • 0
vor 51 Minuten schrieb Tician:

Ich habe jetzt oft von managed und unmanaged Code gehört und weiß auch etwa was es ist. Wie erkenne ich unmanaged Code denn, wie kommst du auf dieses IDisposable? Ich dachte unmanaged Code wäre alles was ich von einer .dll entnehme die nicht automatisch in der IDE enthalten ist (z.B. Public Declare Function BlockInput Lib "user32".... ) oder sowas, wir haben das Schreiben und Lesen aus Dateien in der Schule drangenommen aber auch nur ohne dieses "using".

Ich habe also die Wahl entweder erst alles im Speicher zu machen oder ein using zu benutzen. Und wenn ich das richtig gelesen habe dann muss ich Dispose() aufrufen wenn ich fertig bin, aber wenn mein Code gegen die Wand rennt (also ne Exception wirft) dann wird Dispose() automatisch ausgeführt.

https://msdn.microsoft.com/de-de/library/yh598w02.aspx

Managed Code ist das, was von der Common Language Runtime (CLR) gemanaged wird. Die CLR ist die Laufzeitumgebung, in der dein C#-Code läuft. In der CLR läuft auch der Gargabe Collector, der eben den Speicher reserviert und wieder freigibt. Unmanaged Code ist das, was außerhalb der CLR läuft. Die Klasse TextWriter ruft also Funktionalitäten auf, die außerhalb der CLR liegen. z.B. wenn die Win32-API aufgerufen wird. Die Win32-API ist mit C++ geschrieben und direkt in Maschinencode kompiliert. Sprachen wie z.B. C/C++ besitzen keinen Gargabe Collector. Der Entwickler muss hier selbst für die Speicherreservierung- und Freigebung kümmern. Daher spricht man hier von "unmagaged Code", weil es keine automatische Unterstützung für diese Aufgabe gibt. Die Klasse TextWriter muss also selbst dafür sorgen, dass der Speicher der darunterliegenden Aufrufe bereinigt wird. Dafür wurde das IDisposable-Interface geschaffen, die die Dispose()-Methode besitzt und aufgerufen werden sollte, wenn man es mit solchen Klassen zu tun hat.

Das using ist nur eine syntakische Erleichterung. Folgenden Code:

using(TextWriter writer = new TextWriter(...))
{
    ...
}

könnte man auch folgendermaßen schreiben:

TextWriter writer = new TextWriter(...)

try
{
    ...
}
finally
{
    if (writer != null)
        writer.Dispose();
}

Das using hat nämlich auch die Eigenschaft, dass das Dispose() immer aufgerufen wird, auch wenn eine Exception geworfen wird.

Ein using musst du also so oder so verwenden. Es sei denn, du verwendest eine Bibliothek, um die CSV-Dateien zu erstellen, die das alles für dich abnimmt. Wie z.B. CsvHelper.

Ob eine Klasse das IDisposable-Interface implementiert kann man aus der Dokumentation entnehmen oder man schaut sich die Definition der Klasse in Visual Studio an. Dafür klickst du einfach mit der rechten Maustaste auf den Klassennamen und wählst "Go To Definition" aus oder drückst F12.

bearbeitet von Whiz-zarD

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
  • 0

Also schaue ich mir die Klassen die ich benutze wohl besser genauer an. Ist das IDispose das einzige Anzeichen für unmanaged Code?

Wenn ich das richtig verstehe und faul wäre müsste ich rein theoretisch in meiner Exception also statt sw.Close() einfach ein sw.Dispose() einfügen? Oder brauche ich trotzdem das sw.Close() (wir hatten in der Schule gelernt das das Erzeugen des Objektes eine Datei öffnet; mit sw.WriteLine schreiben wir in die Datei und ohne sw.Close() gibt es keine Datei oder Veränderung da mit sw.Close die Datei erst gespeichert und geschlossen wird)? Oder warum meintest du brauche ich dringend ein using? Ich behandel die csv ja wie eine normale Text-Datei und genauso wird sie auch wieder geschrieben, das Programm funktioniert ja soweit fast einwandfrei.

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
  • 0
vor 5 Stunden schrieb Tician:

catch (Exception ex)

{

Console.WriteLine(ex);

Console.WriteLine("Programm wird beendet, bitte beliebige Taste druecken...");

sw.Close();

sr.Close();

Console.ReadKey();

}

Auch wenn das jetzt alles wieder sehr Lehrreich war würde ich fast behaupten wenn ich jetzt das hier mache:

catch (Exception ex)
            {
                Console.WriteLine(ex);
                Console.WriteLine("Programm wird beendet, bitte beliebige Taste druecken...");
                sw.Close();
                sr.Close();
				sw.Dispose();
                Console.ReadKey();
            }                     

Das sich das Programm trotzdem an der unbehandelten Ausnahme bei sw.Close() aufhängt weil er das schon gar nicht mehr machen kann. Wenn ich das jetzt aber umdrehe und sw.Dispose() zuerst aufrufe denke ich gibt es auch Probleme (ich sollte ja keine Ressourcen freigeben wenn der StreamWriter noch nicht geschlossen wurde).

Wenn ich jetzt also doch ein using() benutze... wann genau wird das Dispose aufgerufen? Direkt am Anfang der Exception oder am Ende? Keine Ahnung wie lange ich heute noch bleibe das ist alles Spekulation basierend auf meinem Verständnis der Dinge, ich probier entweder später oder morgen nochmal rum.

bearbeitet von Tician

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
  • 0

Bei einem using wird Dispose() immer am Ende des Blocks aufgerufen. Beispiel:

Wir haben folgenden Code:

try
{
    using(TextWriter writer = new TextWriter(...))
    {
        // Business-Logik
    }
}
catch(Exception e)
{
    // Exception-Logik
}

Das wäre das selbe, wie das hier:

try
{
    TextWriter writer = new TextWriter(...);

    try
    {
        // Business-Logik
    }
    finally
    {
        if (writer != null)
            writer.Dispose();
    }

}
catch(Exception e)
{
    // Exception-Logik
}

Der Finally-Block wird immer aufgerufen. Komme was wolle. Es ist egal, ob innerhalb der Business-Logik eine Exception geworfen wird oder sie fehlerfrei durchläuft und genau so verhält sich auch das using. Es ruft immer am Ende des Blockes Dispose() auf.

Du solltest aber wirklich erst mal die Grundlagen der Programmierung bzw. der Objektorientierung lernen. Ich sehe da einfach nur Schwarz. Du siehst ja selber, dass dein Code einfach unwartbar und unstrukturiert ist. Du solltest dir erst mal Gedanken machen, welche Aufgaben dein Programm erfüllen soll. Wenn ich den Code richtig verstehe, sehe ich da vier Aufgaben:

  1. CSV-Dateien einlesen
  2. Daten aus dem Internet herunterladen
  3. Daten parsen
  4. CSV-Dateien schreiben

Also sehe ich hier schon mindestens vier Klassen. Du versuchst aber gleich mehrere Aufgaben in einer einzigen Methode zu erledigen und das kann einfach nicht gut ausgehen. Kommentare im Code sind auch fast immer ein Anzeichen dafür, dass der Code unsauber ist. Es gibt eigentlich nur sehr wenige Gründe, warum man ein Kommentar schreiben sollte.

bearbeitet von Whiz-zarD

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
  • 0

Kommentare sind im Prinzip für mich, wenn ich jetzt anfangen würde using() zu benutzen würde ich mir auch minimum dahinter schreiben "braucht kein Exception, ruft Dispose auf" weil ich mir das einfach nicht merken kann. Gib mir ne Woche oder gar einen Monat ohne Programmieren und ich erkenne das using() nicht mehr.

Ich weiß das mein Code grauenhaft ist und du hältst es mir ja auch mit jedem neuen Thread unter die Nase, aber das nehme ich als deine Meinung hin, ich versuche das was ich kann ohne das man mir über ein Forum die Grundlagen neu beibringen muss, aber das Thema hatten wir schon. Wenn ich anfange Klassen zu machen und die einfachsten Dinge (wie die gottverdammten Zugriffsebenen!) nicht hinbekomme dann ist mir und auch anderen nicht geholfen, es raubt mehr Zeit als wenn ich einen Code poste den man (auch wenn es einem die Nägel hochziehen) verstehen kann.

Irgendwann werde ich hoffentlich mal etwas größeres Programmieren und dann wird sich mir vielleicht auch der Sinn von Klassen eher erschließen als bei meinen kleinen Programmen hier.

 

bearbeitet von Tician

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
  • 0
vor 30 Minuten schrieb Tician:

Wenn ich anfange Klassen zu machen und die einfachsten Dinge (wie die gottverdammten Zugriffsebenen!) nicht hinbekomme dann ist mir und auch anderen nicht geholfen, es raubt mehr Zeit als wenn ich einen Code poste den man (auch wenn es einem die Nägel hochziehen) verstehen kann.

Glaube mir mal, deine Probleme beruhen darauf, dass der Code so schlecht geschrieben wurde. ;)
Es ist äußerst schwierig, dort den Überblick zu behalten. Du sagst ja selber, dass du die Kommentare schreibst, um dich daran zu erinnern, was das soll aber so etwas brauchst du bei einem gut strukturierten Code nicht. Es ist ein trugschluss, wenn man meint, man spart Zeit, wenn man den Code hinfrickelt. Ja, mag sein, dass der initiale Aufwand geringer ist aber der Aufwand kommt bei der Fehlersuche und momentan raubt doch die Fehlersuche viel Zeit. ;)

vor 30 Minuten schrieb Tician:

Irgendwann werde ich hoffentlich mal etwas größeres Programmieren und dann wird sich mir vielleicht auch der Sinn von Klassen eher erschließen als bei meinen kleinen Programmen hier.

Wenn dir das schon bei so einem kleinen Programm nicht der Sinn von Klassen erschließt, dann wohl gar nicht. Ich habe dir schon Beispiele genannt, wie man hier vier Klassen designen kann, wenn du das dann immer noch nicht verstehst, wann dann?

Entweder du willst es lernen oder nicht. Wenn du es lernen willst, dann probiere es einfach aus. Versperr dich doch nicht.

bearbeitet von Whiz-zarD

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
Gast
Du kommentierst als Gast. Wenn du bereits einen Account hast kannst du dich hier anmelden.
Diese Frage beantworten...

×   Du hast formatierten Text eingefügt.   Formatierung jetzt entfernen

  Only 75 emoticons maximum are allowed.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Clear editor

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Melde dich an, um diesem Inhalt zu folgen  

×