[C#] Close StreamReader garbage collection

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Is het noodzakelijk dat ik het streamreader object sluit voordat ik null return? Of ruimt de garbage collector het object vanzelf op omdat er geen verwijzingen meer bestaan naar het object (sr == null).

C#:
1
2
3
4
5
6
StreamReader sr = new StreamReader(filePath);

//sr read ..

//Function returns streamreader instance, but on error returns null.
sr = Function(sr);


C#:
1
2
3
4
5
6
7
8
9
10
11
12
Function:
try
{
    //stuff

}
catch
{
    return null;
}

return sr;


Een ander voorbeeld:


code:
1
2
3
4
    static class Reference
    {
        public static Form2 staticForm2 = null;
    }


code:
1
2
Form2 constructor
Reference.staticForm2 = this;


C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Form1:
        private void button_Click(object sender, EventArgs e)
        {
            
            //Create form instance and show when:
            //1. Form2 has never been used or
            //2. Form2 has been used but not visible now.
            if (Reference.staticForm2 == null || Reference.staticForm2.Visible == false)
            {
                Form2 form2 = new Form2();
                form2.Show();
            }
            //If an instance is currently visible, hide the instance and create a new instance (reinitialize) + show.
            else
            {
                Reference.staticForm2.Hide();
                Form2 form2 = new Form2();
                form2.Show();
            }          

        }


In het geval dat de else wordt doorlopen, wordt de huidige instance (1) gehide, een nieuwe instance aangemaakt (2), en aan de variable staticForm2 toegewezen. Wordt instance (1) nu automatisch opgeruimd door NET omdat er geen referenties meer zijn naar het object (staticForm2 verwijst niet meer naar deze instance)?

Dit is volgens mij ook van toepassing als Reference.staticForm2.Visible false is.

Acties:
  • 0 Henk 'm!

  • riezebosch
  • Registratie: Oktober 2001
  • Laatst online: 10-09 11:15
Objecten die IDisposable implementeren gebruiken over het algemeen unmanaged resources en moeten dus expliciet opgeruimd worden. Een best-practice hiervoor is het gebruiken van het using statement:

C#:
1
2
3
4
using (StreamReader r = new StreamReader())
{
   ...
}


Dan wordt het object vanzelf weer opgeruimd zodra je buiten de scope van de using komt. Voor Forms enzo is dit niet nodig omdat deze compleet managed zijn en dus inderdaad opgeruimd worden door de GC als er een references meer naar zijn.

[ Voor 14% gewijzigd door riezebosch op 26-06-2007 12:17 ]

Canon EOS 400D + 18-55mm F3.5-5.6 + 50mm F1.8 II + 24-105 F4L + 430EX Speedlite + Crumpler Pretty Boy Back Pack


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Het streamreader object is in mijn code is min of meer de rode draad door de hele method (eerste code blok). Om nou de hele method in using te zetten lijkt mij wat overdreven, daarom geef ik de voorkeur aan het expliciet opruimen.

is het dan noodzakelijk dat ik eerst het sr object sluit voordat ik null return. Of maakt dat niet uit omdat NET het object opruimt zodra de reference weg is

code:
1
2
sr.Close();
return null;

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 01:56
Verwijderd schreef op dinsdag 26 juni 2007 @ 12:28:
is het dan noodzakelijk dat ik eerst het sr object sluit voordat ik null return.
Op die vraag is al correct geantwoord: JA.
Je StreamReader zal bv een file-resource vasthebben, en die moet weer vrijgegeven worden.
(Kijk ook eens naar try / catch / finally)

Zowiezo wordt de GC niet *direct* aangeroepen van zodra je iets 'op NULL zet'. De GC wordt door de runtime aangeroepen als dat nodig is, en dat het is onvoorspelbaar wanneer dat gebeurd.

[ Voor 37% gewijzigd door whoami op 26-06-2007 12:35 ]

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Oke, bedankt.

Een finally heeft in mijn geval niet zoveel zin omdat als er geen error is, het sr object gereturned wordt en daarmee moet worden verder gewerkt (na regel 6 eerste blok). De sr moet in dat geval open blijven.

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 01:56
Wanneer treedt er bv wel een error op ?
Ik bedoel: kan het zijn dat, als er een error optreedt, je ook nog geen streamreader hebt ?

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 16-09 09:15

Janoz

Moderator Devschuur®

!litemod

Ik vind de constructie een beetje vreemd. Waarom zou je halverwege je stream reader op null moeten zetten als er iets fout gaat? Kun je die function niet gewoon iets laten throwen wat je in het aanroepende deel catched? Ik heb namelijk het vermoeden dat je nu verderop allemaal checks hebt zitten of sr==null en dat er in dat geval niks meer moet gebeuren. Dat lijkt me allemaal een beetje dubbel op.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • EfBe
  • Registratie: Januari 2000
  • Niet online
1) geen exceptions swallowen tenzij de exceptie optreedt voor iets optioneels en niet te voorkomen is (bv config file crap)
2) geen open readers etc. returnen van methods tenzij je weet wat je doet. Een reader is een open resource, en de caller moet dus WETEN dat deze een dispose moet callen. Niet een constructie die te prefereren is, tenzij je dedicated vermeldt bij de method dat het object dat gereturned wordt wel moet worden geclosed en gedisposed.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


Acties:
  • 0 Henk 'm!

  • riezebosch
  • Registratie: Oktober 2001
  • Laatst online: 10-09 11:15
EfBe schreef op dinsdag 26 juni 2007 @ 13:21:
1) geen exceptions swallowen tenzij de exceptie optreedt voor iets optioneels en niet te voorkomen is (bv config file crap)
2) geen open readers etc. returnen van methods tenzij je weet wat je doet. Een reader is een open resource, en de caller moet dus WETEN dat deze een dispose moet callen. Niet een constructie die te prefereren is, tenzij je dedicated vermeldt bij de method dat het object dat gereturned wordt wel moet worden geclosed en gedisposed.
Op punt 2): Is het dan niet sowieso beter de reader als (in) parameter aan de functie mee te geven in plaats van deze lokaal te instantiëren? Zo blijft de caller verantwoordelijk.

Canon EOS 400D + 18-55mm F3.5-5.6 + 50mm F1.8 II + 24-105 F4L + 430EX Speedlite + Crumpler Pretty Boy Back Pack


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 16-09 09:15

Janoz

Moderator Devschuur®

!litemod

Kijk eens naar de gegeven code. De reader is een parameter en binnen de functie wordt hij ineens opgeruimd. Vandaar ook mijn opmerking eerder dat het een wat vreemde constructie is.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Het is ongeveer als volgt:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
//Main execution method
void Method1(bool abc)
{

StreamReader sr = new StreamReader(filePath); 

//Function returns streamreader instance, but on error returns null. 
if (abc == true)
     sr = Function(sr);

if (sr == null)
    return;

//sr read ..

}

//Purpose of the function is to increment the line position of the streamreader instance and return it.
StreamReader Function(StreamrReader sr)
{

int Number1
int Number2
try
{
     Number1 = //retrieve from database.
}
catch
{
     sr.close();
    return null;
}
finally
            {
                //Close the connection.
                if (con.State == ConnectionState.Open)
                    con.Close();
            }

string line;
do
{
    line = sr.ReadLine();
    Number2 = //retrieve number from line.
    
    if (sr.EndOfStream == true)
    {
          sr.Close();
          return null;
    }
} while (Number1 != Number2)

return sr;
}


De reden dat de functie code niet in de hoofdmethod zit is om de hoofdmethode overzichtelijker te maken.

[ Voor 8% gewijzigd door Verwijderd op 26-06-2007 14:10 ]


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 16-09 09:15

Janoz

Moderator Devschuur®

!litemod

Ten eerste vind ik je indenting een beetje rot, maar daar gaat het hier nu natuurlijk niet om. Wat is de reden om de boel te catchen binnen Function? Dat lijkt mij namelijk een beetje overbodig. Zet de try catch gewoon in method1 en laat function de exception throwen.

@indenting opmerking hieronder: Ah ok, dat verklaart :).. Ik dacht dat je je bestaande code gekopieerd had en dan dingen weggehaald had. Maar code schrijven in een non fixed width textarea is inderdaad dikke ruk.

[ Voor 28% gewijzigd door Janoz op 26-06-2007 14:24 ]

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Goed punt, dat klinkt logisch. Ik zal het gaan uitwerken.

Sorry voor de indenting, dat gaat wat lastig by het schrijven van code op het forum. In Visual Studio staat het allemaal netjes. ;)
Pagina: 1