Avatar billede Slettet bruger
31. januar 2008 - 22:31 Der er 17 kommentarer og
1 løsning

Object Reference - Stirret mig blind

Hejsa.
Jeg er ved at lave et lille program, der blandt andet skal kunne administrere nogle servere på en liste i en txt-fil.
Jeg har blandt andre en metode - AddServer, der som navnet siger tilføjer en server til listen over servere.

Før serveren addes testes på om serveren allerede eksisterer på listen.

I mit Main program kalder jeg metoden AddServer:

ServerManagement serverManagement = new ServerManagement();

                serverManagement.AddServer("TestServer3", "10.0.0.3");
                serverManagement.AddServer("TestServer4", "10.0.0.4");
                serverManagement.AddServer("TestServer5", "10.0.0.5");

Metoden AddServer er opbygget således:

// ****************************************************************************
        // AddServer() - Opretter en ny server til server-listen
        // ****************************************************************************
        public void AddServer(string serverName, string ipAddress)
        {
            StreamWriter writer = null;
           
            try
            {
                writer = new StreamWriter("ServerList.txt", true);
                if (!ServerExists(serverName))
                {
                    writer.WriteLine("");
                    writer.WriteLine(serverName);
                    writer.WriteLine(ipAddress);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                writer.Close();
                writer.Dispose();
            }
        }

Metoden, hvor der tjekkes om en server allerede er på listen er opbygget således:

// ****************************************************************************
        // ServerExists() - Tjekker om en server findes på listen
        // ****************************************************************************
        private bool ServerExists(string serverName)
        {
            bool serverExists = false;
            ArrayList serverList = ReturnServerList();

            try
            {
                if (serverList != null && serverList.Count > 0)
                {
                    Server server;
                    for (int i = 0; i < serverList.Count; i++)
                    {
                        server = (Server)serverList[i];
                        if (server.serverName.Equals(serverName))
                        {
                            serverExists = true;
                            break;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return serverExists;
        }

Når jeg kører programmet får jeg en fejl:

System.NullReferenceException: Objektreferencen er ikke indstillet ti
mst af et objekt.
  ved Servers.ServerManagement.AddServer(String serverName, String i
D:\My Documents\Visual Studio 2008\Projects\Servers\Servers\ServerMa
:linje 29
  ved ConsoleApplication1.Program.Main(String[] args) i D:\My Docume
Studio 2008\Projects\Servers\ConsoleApplication1\Program.cs:linje 17

Det sjove er at hvis jeg laver ServerExists metoden om til public og kalder denne metode direkte fra mit program med et servernavn og en ip, så virker det fint.
Det samme gælder for AddServer, hvis jeg kalder denne mtode uden at denne gør brug af ServerExists metoden - altså hvor der ikke testes på om serveren allerede eksisterer.

Jeg har simpelthen stirret mig blind på problemet. Forstår ikke hvilket objekt, der ikke er oprettet en reference til.

Håber nogen kan se problemet og hjælpe med et hint.
Avatar billede kalp Novice
31. januar 2008 - 22:36 #1
sikker på det ikke er metoden ReturnServerList() der fejler?
Avatar billede Syska Mester
31. januar 2008 - 22:37 #2
Hvad er linje 29 ?

// ouT
Avatar billede Slettet bruger
31. januar 2008 - 23:10 #3
Metoden ReturnServerList er opbygget som følger og virker fint i stort set alle henseender:

// ****************************************************************************
        // ReturnServerList() - Henter liste over servere fra tekstfil
        // ****************************************************************************
        public ArrayList ReturnServerList()
        {
            ArrayList serverList = new ArrayList();
            StreamReader reader = null;
            string serverName, ipAddress;
            Server server;

            try
            {
                reader = new StreamReader("ServerList.txt");
                while (!reader.EndOfStream)
                {
                    serverName = reader.ReadLine();
                    if (!String.IsNullOrEmpty(serverName))
                    {
                        ipAddress = reader.ReadLine();

                        server = new Server();
                        server.serverName = serverName;
                        server.ipAddress = ipAddress;
                        serverList.Add(server);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                reader.Close();
                reader.Dispose();
            }

            return serverList;
        }

Der var et lignende problem som det nuværende på et tidspunkt med en anden metode, hvor en server slettes og listen bliver gen-bygget, men det virkede så pludseligt...

Men jeg kan altså ikke rigtig se hvad for en reference, der ikke er sat. Som sagt virker det fint, hvis jeg kalder metoderne fra programmet / eller undlader at lave tjek på om serveren allerede eksisterer.

Linie 29 er } i metoden AddServer - altså den bracket, der afslutter try.
Avatar billede erikjacobsen Ekspert
31. januar 2008 - 23:15 #4
Jeg tror ikke det er linie 29 - men:

Du skriver 3 linier: tom, servernavn, ipadresse

Du læser 2 linier: serverName = reader.ReadLine();  og  ipAddress = reader.ReadLine();

Det må da gå galt ... om det så giver den fejl du oplever, det ved jeg ikke.
Avatar billede powerpunk Nybegynder
01. februar 2008 - 08:51 #5
Jeg har forsøgt at genskabe et program med dine funktioner.

Dit problem ser ud til at være at du i Addserver åbner filen "ServerList.txt"
Den er nu låst.
Herefter kalder du ServerExists som kalder ReturnServerList som OGSÅ forsøger at åbne "ServerList.txt", men linien
  reader = new StreamReader("ServerList.txt");
Fejler, fordi der ikke er adgang til filen.
Avatar billede powerpunk Nybegynder
01. februar 2008 - 08:53 #6
Derfor virker AddServer og ServerExists også isoleret, fordi de så ikke begge to forsøger at låse filen...
Avatar billede powerpunk Nybegynder
01. februar 2008 - 09:14 #7
Hvis jeg måtte "pille" lidt ved din kode, ville jeg nok gøre noget i denne retning:

  public class ServerManagement : IDisposable
  {
    private readonly StreamReader reader;
    private readonly StreamWriter writer;

    public ServerManagement(string filename)
    {
      FileStream file = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite);
      reader = new StreamReader(file);
      writer = new StreamWriter(file);
    }

[...]
    //************************************************************************
    // AddServer() - Opretter en ny server til server-listen
    //************************************************************************
    public void AddServer(string serverName, string ipAddress)
    {
      if (!ServerExists(serverName))
      {
        writer.WriteLine("");
        writer.WriteLine(serverName);
        writer.WriteLine(ipAddress);
      }
    }

    // ****************************************************************************
    // ReturnServerList() - Henter liste over servere fra tekstfil
    // ****************************************************************************
    public ArrayList ReturnServerList()
    {
      ArrayList serverList = new ArrayList();
      string serverName, ipAddress;
      Server server;

      while (!reader.EndOfStream)
      {
        serverName = reader.ReadLine();
        if (!String.IsNullOrEmpty(serverName))
        {
          ipAddress = reader.ReadLine();

          server = new Server();
          server.serverName = serverName;
          server.ipAddress = ipAddress;
          serverList.Add(server);
        }
      }

      return serverList;
    }
[...]

    #region IDisposable Members

    public void Dispose()
    {
      Dispose(true);
      GC.SupressFinalize(this);
    }

    protected Dispose(bool disposing)
    {
      if (disposing)
      {
        writer.Dispose();
        reader.Dispose();
      }
    }

    ~ServerManagement()
    {
      Dispose(false);
    }
    #endregion   
  }

Og så vil jeg iøvrigt give dig det tip at bruge
  catch(Exception ex)
  {
    throw;
  }
i stedet for
  catch(Exception ex)
  {
    throw ex;
  }
hvis du endelig skal gen-throw'e. 'throw ex' laver rod i din stack trace - det er derfor du ikke får at vide at fejlen er sket nede i ReturnServerList...
Avatar billede kalp Novice
01. februar 2008 - 09:33 #8
Jeg har hele tiden ikke fattet pointen i at fange en exception for at kaste den igen.

I denne sammenhæng altså.
Jeg bruger det selv til, at logge en fejl hvorefter jeg kaster en bruger custom exception.

Det giver mening.. jeg kan ikke se meningen i det her:)

Han har selvfølgelig Finally med i den ene metode for at lukke for en stream, men ikke i den anden.
Avatar billede powerpunk Nybegynder
01. februar 2008 - 10:00 #9
kalp -> Enig. Sålænge der ikke sker andet i handleren.
Der kan naturligvis være situationer hvor du gerne vil gøre et eller andet når exceptionen bliver fanget (skrive i en log eller lign.) og så alligevel kaste den videre.

Men finally blokken kunne sagtens være der uden catch... eller endnu pænere

  using(writer = new StreamWriter("ServerList.txt", true))
  {
    if (!ServerExists(serverName))
    {
      writer.WriteLine("");
      writer.WriteLine(serverName);
      writer.WriteLine(ipAddress);
    }
  }

Men nu er en del af problemet jo at han gerne vil tilgå sin fil i en underfunktion... hvis readeren i ReturnServerList disposer, lukker den streamen (som er nødt til at være delt med writeren, og næste write operation vil fejle.
Derfor mit forslag med at gøre reader og writer til private members i ServerManagement klassen og dispose dem sammen med ServerManagement objektet.
Avatar billede Slettet bruger
01. februar 2008 - 12:20 #10
Hejsa og tak for input.
Jeg har nu lavet min servermanagement klasse om til følgende, men kan så ikke lige finde ud af at implementere det med #region.

using System;
using System.Threading;
using System.Net;
using System.Net.NetworkInformation;
using System.IO;
using System.Collections;
using System.Collections.Generic;

namespace Servers
{
    public class ServerManagement : IDisposable
    {
        private readonly StreamReader reader;
        private readonly StreamWriter writer;
       
        // ****************************************************************************
        // Konstruktør() - Konstruktør uden parametre
        // ****************************************************************************
        public ServerManagement()
        {}

        // ****************************************************************************
        // Konstruktør() - Konstruktør med parametre til filhåndtering
        // ****************************************************************************
        public ServerManagement(bool workWithTextFile)
        {
            try
            {
                FileStream file = new FileStream("ServerList.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                reader = new StreamReader(file);
                writer = new StreamWriter(file);
            }
            catch (Exception ex)
            {
                throw;
            }
        }
       
        // ****************************************************************************
        // AddServer() - Opretter en ny server til server-listen
        // ****************************************************************************
        public void AddServer(string serverName, string ipAddress)
        {           
            try
            {
                if (!ServerExists(serverName))
                {
                    writer.WriteLine("");
                    writer.WriteLine(serverName);
                    writer.WriteLine(ipAddress);
                }
            }
            catch (Exception ex)
            {
                throw;
            }
        }

        // ****************************************************************************
        // RebuildServerList() - Opretter ny liste over servere
        // ****************************************************************************
        public void RebuildServerList(ArrayList serverList)
        {
            try
            {
                Server server;
                for (int i = 0; i < serverList.Count; i++)
                {
                    server = (Server)serverList[i];

                    writer.WriteLine("");
                    writer.WriteLine(server.serverName);
                    writer.WriteLine(server.ipAddress);
                }
            }
            catch (Exception ex)
            {
                throw;
            }
        }

        // ****************************************************************************
        // RemoveServer() - Fjerner en server fra server-listen
        // ****************************************************************************
        public void RemoveServer(string serverName)
        {
            ArrayList serverList = ReturnServerList();
           
            try
            {
                if (serverList != null && serverList.Count > 0)
                {
                    Server server;
                    for (int i = 0; i < serverList.Count; i++)
                    {
                        server = (Server)serverList[i];
                        if (server.serverName.Equals(serverName))
                        {
                            serverList.RemoveAt(i);
                        }
                    }
                    RebuildServerList(serverList);
                }
            }
            catch (Exception ex)
            {
                throw;
            }
        }

        // ****************************************************************************
        // ReturnServerList() - Henter liste over servere fra tekstfil
        // ****************************************************************************
        public ArrayList ReturnServerList()
        {
            ArrayList serverList = new ArrayList();
            string serverName, ipAddress;
            Server server;

            try
            {
                while (!reader.EndOfStream)
                {
                    serverName = reader.ReadLine();
                    if (!String.IsNullOrEmpty(serverName))
                    {
                        ipAddress = reader.ReadLine();

                        server = new Server();
                        server.serverName = serverName;
                        server.ipAddress = ipAddress;
                        serverList.Add(server);
                    }
                }
            }
            catch (Exception ex)
            {
                throw;
            }

            return serverList;
        }

        // ****************************************************************************
        // ServerExists() - Tjekker om en server findes på listen
        // ****************************************************************************
        private bool ServerExists(string serverName)
        {
            bool serverExists = false;
            ArrayList serverList = ReturnServerList();

            try
            {
                if (serverList != null && serverList.Count > 0)
                {
                    Server server;
                    for (int i = 0; i < serverList.Count; i++)
                    {
                        server = (Server)serverList[i];
                        if (server.serverName.Equals(serverName))
                        {
                            serverExists = true;
                            break;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw;
            }

            return serverExists;
        }

        // ****************************************************************************
        // PingServer() - Pinger en given server x-antal gange og returnerer antal svar
        // ****************************************************************************
        public bool PingServer(string ipAddress)
        {
            bool success = false;

            try
            {
                Ping ping = new Ping();
                PingReply reply = ping.Send(ipAddress);
                if (reply.Status == IPStatus.Success)
                {
                    success = true;
                }
            }
            catch (Exception ex)
            {
                throw;
            }

            Thread.Sleep(1000);
            return success;
        }
    }
}

Nu får jeg en fejl - nok fordi jeg ikke har det med region med, om at jeg ikke implementerer Dispose();
Hvis jeg fjerner IDisposable fra klassen - altså at den benytter dette interfase, så kompilerer den fint, men adder ingen servere.

Jeg bruger følgende kode fra mit Main program til at teste med:

Console.WriteLine("Tilføjer servere til listen over servere...");
               
                ServerManagement serverManagement = new ServerManagement(true);
                serverManagement.AddServer("testserver1", "192.168.0.2");
                serverManagement.AddServer("testserver2", "192.168.0.3");
                serverManagement.AddServer("testserver3", "192.168.0.4");

                Console.WriteLine("n\\Serverlisten indeholder nu følgende servere...");
                ArrayList serverList = serverManagement.ReturnServerList();
                Server server;
                for (int i = 0; i < serverList.Count; i++)
                {
                    server = (Server)serverList[i];
                    Console.WriteLine(server.serverName + " - " + server.ipAddress);
                }

                Console.WriteLine("Tilføjer servere til listen over servere...");
                serverManagement.AddServer("testserver1", "192.168.0.2");
                serverManagement.AddServer("testserver2", "192.168.0.3");
                serverManagement.AddServer("testserver4", "192.168.0.12");

                Console.WriteLine("n\\Serverlisten indeholder nu følgende servere...");
                serverList = serverManagement.ReturnServerList();
                for (int i = 0; i < serverList.Count; i++)
                {
                    server = (Server)serverList[i];
                    Console.WriteLine(server.serverName + " - " + server.ipAddress);
                }

                Console.Read();

Det skriver bare at nu tilføjes der servere til listen, men ingen servere bliver tilføjet.

Med venlig hilsen,
Thomas
Avatar billede Slettet bruger
01. februar 2008 - 12:24 #11
Nu kan jeg jo ikke teste det lige nu, men hvad sker der egentlig med min metode kaldet RebuildServerList?
Denne metode opretter jo en helt ny txt-fil og overskriver den gamle ud fra den medsendte serverList ArrayList fra RemoveServer metoden.

Men nu da StreamWriter objektet sættes højere oppe - altså i konstruktøren har jeg jo ikke mulighed for at specificere om der skal være tale om apend eller overwrite.
Avatar billede powerpunk Nybegynder
01. februar 2008 - 14:20 #12
Jeg fik lavet et par syntaksfejl i dispose metoden kan jeg se. prøv denne her:

        #region IDisposable Members

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected void Dispose(bool disposing)
        {
            if (disposing)
            {
                writer.Dispose();
                reader.Dispose();
            }
        }

        ~ServerManagement()
        {
            Dispose(false);
        }
        #endregion

Derudover har erikjacobsen også fat i at du skriver tre linier men kun læser to. Og så er der lidt bøvl jeg ikke havde forudset med at have en writer og en reader kørende simultant på samme stream. rettelse i ReturnServerlist:

[...]
  reader.BaseStream.Position = 0; //Spol readeren tilbage til starten af filen
  while (!reader.EndOfStream)
  {
    reader.ReadLine();
    serverName = reader.ReadLine();
    if (!String.IsNullOrEmpty(serverName))
[...]

Writeren får heller ikke flushet sine ændringer til filen... rettelse i ServerManagement constructor:

[...]
  writer = new StreamWriter(file);
  writer.AutoFlush = true;
[...]

og så bør din testkode rettes til så den kalder Dispose(): (using statement'et er en pæn løsning på dette...)

  Console.WriteLine("Tilføjer servere til listen over servere...");

  using(ServerManagement serverManagement = new ServerManagement(true))
  {
    serverManagement.AddServer("testserver1", "192.168.0.2");
    serverManagement.AddServer("testserver2", "192.168.0.3");
    serverManagement.AddServer("testserver3", "192.168.0.4");

    Console.WriteLine("n\\Serverlisten indeholder nu følgende servere...");
    ArrayList serverList = serverManagement.ReturnServerList();
    Server server;
    for (int i = 0; i < serverList.Count; i++)
    {
      server = (Server)serverList[i];
      Console.WriteLine(server.serverName + " - " + server.ipAddress);
    }

    Console.WriteLine("Tilføjer servere til listen over servere...");
    serverManagement.AddServer("testserver1", "192.168.0.2");
    serverManagement.AddServer("testserver2", "192.168.0.3");
    serverManagement.AddServer("testserver4", "192.168.0.12");
    serverManagement.AddServer("testserver5", "192.168.0.11");

    Console.WriteLine("n\\Serverlisten indeholder nu følgende servere...");
    serverList = serverManagement.ReturnServerList();
    for (int i = 0; i < serverList.Count; i++)
    {
      server = (Server)serverList[i];
      Console.WriteLine(server.serverName + " - " + server.ipAddress);
    }
  }
  Console.Read();
}
Avatar billede Slettet bruger
01. februar 2008 - 17:52 #13
Hej. Jamen det virker sgu :-)
Min klasse ser nu ud som følger efter ændringerne:

using System;
using System.Threading;
using System.Net;
using System.Net.NetworkInformation;
using System.IO;
using System.Collections;
using System.Collections.Generic;

namespace Servers
{
    public class ServerManagement : IDisposable
    {
        private readonly StreamReader reader;
        private readonly StreamWriter writer;
       
        // ****************************************************************************
        // Konstruktør() - Konstruktør uden parametre
        // ****************************************************************************
        public ServerManagement()
        {}

        // ****************************************************************************
        // Konstruktør() - Konstruktør med parametre til filhåndtering
        // ****************************************************************************
        public ServerManagement(bool workWithTextFile)
        {
            try
            {
                FileStream file = new FileStream("ServerList.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                reader = new StreamReader(file);
                writer = new StreamWriter(file);
                writer.AutoFlush = true;
            }
            catch (Exception ex)
            {
                throw;
            }
        }
       
        // ****************************************************************************
        // AddServer() - Opretter en ny server til server-listen
        // ****************************************************************************
        public void AddServer(string serverName, string ipAddress)
        {           
            try
            {
                if (!ServerExists(serverName))
                {
                    writer.WriteLine("");
                    writer.WriteLine(serverName);
                    writer.WriteLine(ipAddress);
                }
            }
            catch (Exception ex)
            {
                throw;
            }
        }

        // ****************************************************************************
        // RebuildServerList() - Opretter ny liste over servere
        // ****************************************************************************
        public void RebuildServerList(ArrayList serverList)
        {
            try
            {
                Server server;
                for (int i = 0; i < serverList.Count; i++)
                {
                    server = (Server)serverList[i];

                    writer.WriteLine("");
                    writer.WriteLine(server.serverName);
                    writer.WriteLine(server.ipAddress);
                }
            }
            catch (Exception ex)
            {
                throw;
            }
        }

        // ****************************************************************************
        // RemoveServer() - Fjerner en server fra server-listen
        // ****************************************************************************
        public void RemoveServer(string serverName)
        {
            ArrayList serverList = ReturnServerList();
           
            try
            {
                if (serverList != null && serverList.Count > 0)
                {
                    Server server;
                    for (int i = 0; i < serverList.Count; i++)
                    {
                        server = (Server)serverList[i];
                        if (server.serverName.Equals(serverName))
                        {
                            serverList.RemoveAt(i);
                        }
                    }
                    RebuildServerList(serverList);
                }
            }
            catch (Exception ex)
            {
                throw;
            }
        }

        // ****************************************************************************
        // ReturnServerList() - Henter liste over servere fra tekstfil
        // ****************************************************************************
        public ArrayList ReturnServerList()
        {
            ArrayList serverList = new ArrayList();
            string serverName, ipAddress;
            Server server;

            try
            {
                reader.BaseStream.Position = 0;
                while (!reader.EndOfStream)
                {
                    serverName = reader.ReadLine();
                    if (!String.IsNullOrEmpty(serverName))
                    {
                        ipAddress = reader.ReadLine();

                        server = new Server();
                        server.serverName = serverName;
                        server.ipAddress = ipAddress;
                        serverList.Add(server);
                    }
                }
            }
            catch (Exception ex)
            {
                throw;
            }

            return serverList;
        }

        // ****************************************************************************
        // ServerExists() - Tjekker om en server findes på listen
        // ****************************************************************************
        private bool ServerExists(string serverName)
        {
            bool serverExists = false;
            ArrayList serverList = ReturnServerList();

            try
            {
                if (serverList != null && serverList.Count > 0)
                {
                    Server server;
                    for (int i = 0; i < serverList.Count; i++)
                    {
                        server = (Server)serverList[i];
                        if (server.serverName.Equals(serverName))
                        {
                            serverExists = true;
                            break;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw;
            }

            return serverExists;
        }

        // ****************************************************************************
        // PingServer() - Pinger en given server x-antal gange og returnerer antal svar
        // ****************************************************************************
        public bool PingServer(string ipAddress)
        {
            bool success = false;

            try
            {
                Ping ping = new Ping();
                PingReply reply = ping.Send(ipAddress);
                if (reply.Status == IPStatus.Success)
                {
                    success = true;
                }
            }
            catch (Exception ex)
            {
                throw;
            }

            Thread.Sleep(1000);
            return success;
        }

        #region IDisposable Members
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected void Dispose(bool disposing)
        {
            if (disposing)
            {
                writer.Dispose();
                reader.Dispose();
            }
        }

        ~ServerManagement()
        {
            Dispose(false);
        }
        #endregion
    }
}

Og mit Main program:

Console.WriteLine("Tilføjer servere til listen over servere...");
               
                ServerManagement serverManagement = new ServerManagement(true);
                serverManagement.AddServer("testserver1", "192.168.0.2");
                serverManagement.AddServer("testserver2", "192.168.0.3");
                serverManagement.AddServer("testserver3", "192.168.0.4");

                Console.WriteLine("n\\Serverlisten indeholder nu følgende servere...");
                ArrayList serverList = serverManagement.ReturnServerList();
                Server server;
                for (int i = 0; i < serverList.Count; i++)
                {
                    server = (Server)serverList[i];
                    Console.WriteLine(server.serverName + " - " + server.ipAddress);
                }

                Console.WriteLine("Tilføjer servere til listen over servere...");
                serverManagement.AddServer("testserver1", "192.168.0.2");
                serverManagement.AddServer("testserver2", "192.168.0.3");
                serverManagement.AddServer("testserver4", "192.168.0.12");

                Console.WriteLine("n\\Serverlisten indeholder nu følgende servere...");
                serverList = serverManagement.ReturnServerList();
                for (int i = 0; i < serverList.Count; i++)
                {
                    server = (Server)serverList[i];
                    Console.WriteLine(server.serverName + " - " + server.ipAddress);
                }

                serverManagement.Dispose();

                Console.Read();

Jeg kalder Dispose() i bunden af Main programmet. Var det det du mente?
Jeg ved godt jeg ikke har bygget det op med en using statement, men jeg er sådan set bare vandt til at gøre det på den anden måde og vil egentlig helst holde fast ved den lidt endnu.

Som du måske har bemærket er det mest på hobby-plan jeg skriver kode, men så er det jo godt at der er folk som dig til at redde os ud af problemerne :-)

Smidder du lige et svar?
Avatar billede powerpunk Nybegynder
01. februar 2008 - 22:19 #14
Svar!

Hovedsagen er at få kaldt Dispose, ja. Fidusen ved at bruge using (eller try/finally) er at du er sikker på at den bliver kaldt. I dit tilfælde bliver den sprunget over hvis der bliver smidt en exception et sted.
Avatar billede Slettet bruger
01. februar 2008 - 22:40 #15
Super. Mange tak for din hjælp!
Avatar billede Slettet bruger
02. februar 2008 - 23:38 #16
powerpunk, der er lige et lille problem mere. Måske gider du hjælpe?
Det virkede fint med at tilføje servere, men når jeg nu tester på metoden RemoveServer, hvor serverlisten hentes fra txt-filen og serveren fjernes fra arraylisten, hvorefter den opdaterede arrayliste sendes til metoden RebuildServerList, hvor den opdaterede liste skal skrives til txt-filen, så fjernes serveren ikke fra txt-filen.

Jeg paster lige klassen og mit Main program ind for overskuelighedens skyld:

using System;
using System.Threading;
using System.Net;
using System.Net.NetworkInformation;
using System.IO;
using System.Collections;
using System.Collections.Generic;

namespace Servers
{
    public class ServerManagement : IDisposable
    {
        private readonly StreamReader reader;
        private readonly StreamWriter writer;
       
        // ****************************************************************************
        // Konstruktør() - Konstruktør uden parametre
        // ****************************************************************************
        public ServerManagement()
        {}

        // ****************************************************************************
        // Konstruktør() - Konstruktør med parametre til filhåndtering
        // ****************************************************************************
        public ServerManagement(bool workWithTextFile)
        {
            try
            {
                FileStream file = new FileStream("ServerList.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                reader = new StreamReader(file);
                writer = new StreamWriter(file);
                writer.AutoFlush = true;
            }
            catch (Exception)
            {
                throw;
            }
        }
       
        // ****************************************************************************
        // AddServer() - Opretter en ny server til server-listen
        // ****************************************************************************
        public void AddServer(string serverName, string ipAddress)
        {           
            try
            {
                if (!ServerExists(serverName))
                {
                    writer.WriteLine("");
                    writer.WriteLine(serverName);
                    writer.WriteLine(ipAddress);
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

        // ****************************************************************************
        // RebuildServerList() - Opretter ny liste over servere
        // ****************************************************************************
        public void RebuildServerList(ArrayList serverList)
        {
            try
            {
                Server server;
                for (int i = 0; i < serverList.Count; i++)
                {
                    server = (Server)serverList[i];

                    writer.WriteLine("");
                    writer.WriteLine(server.serverName);
                    writer.WriteLine(server.ipAddress);
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

        // ****************************************************************************
        // RemoveServer() - Fjerner en server fra server-listen
        // ****************************************************************************
        public void RemoveServer(string serverName)
        {
            ArrayList serverList = ReturnServerList();
           
            try
            {
                if (serverList != null && serverList.Count > 0)
                {
                    Server server;
                    for (int i = 0; i < serverList.Count; i++)
                    {
                        server = (Server)serverList[i];
                        if (server.serverName.Equals(serverName))
                        {
                            serverList.RemoveAt(i);
                        }
                    }
                    RebuildServerList(serverList);
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

        // ****************************************************************************
        // ReturnServerList() - Henter liste over servere fra tekstfil
        // ****************************************************************************
        public ArrayList ReturnServerList()
        {
            ArrayList serverList = new ArrayList();
            string serverName, ipAddress;
            Server server;

            try
            {
                reader.BaseStream.Position = 0;
                while (!reader.EndOfStream)
                {
                    serverName = reader.ReadLine();
                    if (!String.IsNullOrEmpty(serverName))
                    {
                        ipAddress = reader.ReadLine();

                        server = new Server();
                        server.serverName = serverName;
                        server.ipAddress = ipAddress;
                        serverList.Add(server);
                    }
                }
            }
            catch (Exception)
            {
                throw;
            }

            return serverList;
        }

        // ****************************************************************************
        // ServerExists() - Tjekker om en server findes på listen
        // ****************************************************************************
        private bool ServerExists(string serverName)
        {
            bool serverExists = false;
            ArrayList serverList = ReturnServerList();

            try
            {
                if (serverList != null && serverList.Count > 0)
                {
                    Server server;
                    for (int i = 0; i < serverList.Count; i++)
                    {
                        server = (Server)serverList[i];
                        if (server.serverName.Equals(serverName))
                        {
                            serverExists = true;
                            break;
                        }
                    }
                }
            }
            catch (Exception)
            {
                throw;
            }

            return serverExists;
        }

        // ****************************************************************************
        // PingServer() - Pinger en given server x-antal gange og returnerer antal svar
        // ****************************************************************************
        public bool PingServer(string ipAddress)
        {
            bool success = false;

            try
            {
                Ping ping = new Ping();
                PingReply reply = ping.Send(ipAddress);
                if (reply.Status == IPStatus.Success)
                {
                    success = true;
                }
            }
            catch (Exception)
            {
                throw;
            }

            Thread.Sleep(1000);
            return success;
        }

        // ****************************************************************************
        // Dispose() - Disposer objektet
        // ****************************************************************************
        #region IDisposable Members
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected void Dispose(bool disposing)
        {
            if (disposing)
            {
                writer.Dispose();
                reader.Dispose();
            }
        }

        ~ServerManagement()
        {
            Dispose(false);
        }
        #endregion
    }
}


Og Main programmet:

Console.WriteLine("Fjerner server fra listen...");
               
                ServerManagement serverManagement = new ServerManagement(true);
                serverManagement.RemoveServer("testserver2");

                serverManagement.Dispose();

                Console.Read();

Jeg har selvfølgelig sørget for at testserver2 er skrevet ind i tekstfilen manuelt først :-)

Kan du evt. se hvor jeg går galt i byen?
Avatar billede powerpunk Nybegynder
04. februar 2008 - 08:47 #17
Uha... Jeg er bange for, at vi så småt er ved at bevæge os ud i noget snavs ;-)

Problemet er, at når du kalder RebuildServerList står din StreamWriter og peger på slutningen af filen. Du får med andre ord ikke slettet noget, men skriver hele din ServerList til enden af filen.

Du er nok nødt til at starte din RebuildServerList med noget i retning af:

  //Luk den gamle stream
  writer.Close();
  reader.Close();

  //Opret ny, tom fil, som overskriver den gamle.
  FileStream fs = new FileStream("serverlist.txt", FileMode.Create, FileAccess.ReadWrite);

  //Genskab StreamWriter og StreamReader
  writer = new StreamWriter(fs);
  reader = new StreamReader(fs);

Jeg begynder at spekulere på, om ikke du ville være bedre stillet ved at begrænse din fil I/O til at læse hele filen til at starte med og så skrive hele listen til filen når du slutter...
Avatar billede Slettet bruger
04. februar 2008 - 09:21 #18
Hej powerpunk.
Tak for dit forslag. Jeg har kigget lidt i en bog om windows forms, hvor der er beskrevet noget med DataSet og XML og jeg tror faktisk at jeg vil springe ud i at prøve at ændre min løsning til noget med XML. Så bliver det måske også mere enkelt at opdatere filen vha. DataAdapter?
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester