[C#] Threads, StreamReaders en de documentatie...

Pagina: 1
Acties:
  • 123 views sinds 30-01-2008
  • Reageer

  • whoami
  • Registratie: December 2000
  • Laatst online: 22:02
Ik ben net tegen een vreemd probleem opgelopen.

Ik heb in m'n C# programma een Thread object die een bepaalde functie uitvoert.
Die functie zag er ongeveer zo uit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
while (this.IsRunning)
{

  while ( (inputLine = Reader.ReadLine()) != null )
   {
       // Do some stuff.
   }

   Thread.Sleep(500);
}

Reader.Close();


Deze code zou dus, zolang IsRunning op true staat, iedere keer de stream moeten gaan checken of er iets te lezen valt. Indien er niets te lezen is op de stream, dan moet hij een beetje slapen.
Nu had ik het probleem dat m'n thread blijkbaar ergens 'vastliep', of stond te wachten. Na enig zoek en debug-werk, vond ik dat het probleem hier lag:
code:
1
while ( (inputLine = Reader.ReadLine() ) != null )

Zolang er dus iets te lezen viel, moest m'n reader lezen, indien er niets op de stream te lezen is, dan zou ReadLine null moeten returnen volgens de .NET documentatie, en moet die lus dus beëindigd worden.
Dat was dus niet het geval. Blijkbaar 'hangt' of 'wacht' die ReadLine als er niets uit te lezen valt. M'n programma blokkeerde niet, maar m'n thread ging niet verder, m'n lus werd niet beëindigd, m'n cursor bleef tijdens het debuggen maar op die regel staan.
Ik heb die regel toen veranderd naar:
code:
1
2
3
while ( Reader.Peek() != - 1)
{
   inputLine = Reader.ReadLine();

(Peek kijkt of er nog iets te lezen valt, en indien dit niet het geval is, returned die functie -1).
En toen was het blijkbaar opgelost.

Iemand die ook al zoiets heeft meegemaakt of er een verklaring voor heeft? Of deed ik misschien toch nog iets fout?

https://fgheysels.github.io/


  • Freak_NL
  • Registratie: Juli 2000
  • Laatst online: 20-07 09:47
Volgens mij klopt het wel, de Reader blijft gewoon wachten tot er ook daadwerkelijk een line gelezen is met ReadLine(), of de betreffende stream nou nog lines heeft of niet. Ik vermoed dat de Reader daar pas null retourneerd als de stream expliciet afgesloten is.

  • whoami
  • Registratie: December 2000
  • Laatst online: 22:02
Je zou wel eens gelijk kunnen hebben.
Dit vond ik in de doc's.
StreamReader.ReadLine Method
Reads a line of characters from the current stream and returns the data as a string.
Return Value
The next line from the input stream, or a null reference (Nothing in Visual Basic) if the end of the input stream is reached.
Dus, ik dacht, als ik een readline doe, en er staat niets op de stream, dan is 'the end of the input stream' ook bereikt, dus zal ik wel een null terugkrijgen.

https://fgheysels.github.io/


Verwijderd

Volgens mij hangt dit ook af van de onderliggende Stream. Bij bijv. de StdIn stream blijft hij ook hangen ( Console.ReadLine blijft ook wachten op input... ). Waarschijnlijk 'called' je Reader dus gewoon een functie op de onderliggende Stream ( waarschijnlijk Stream.Read() ) welke dus blijft 'hangen'. Misschien dat je dit uit kunt zoeken met een IL dissasembler oid :) .

  • Freak_NL
  • Registratie: Juli 2000
  • Laatst online: 20-07 09:47
Het komt er denk ik op neer dat een Stream best wel leeg mag zijn zonder dat je daarmee het einde van de Stream hebt bereikt. :)

  • whoami
  • Registratie: December 2000
  • Laatst online: 22:02
Hmm...
Ik heb het probleem gevonden. Dit is wel zeer vreemd.

Ik checkte dus of er iets te lezen was op de stream door de Peek() method van de StreamReader te gebruiken:
code:
1
while ( sr.Peek() > -1)

Indien dit true is, dan is er iets te lezen op de stream.

Echter, die conditie werd nooit meer true na een tijdje, terwijl ik wist dat er zeker data op de stream moest zitten.
Ik heb het dan veranderd naar:
code:
1
while (OnderliggendeStream.DataAvailable )

en dan werkt het wel....
Gebruik ik nu die Peek verkeerd, of zit er een bugje in die StreamReader::Peek() method?

https://fgheysels.github.io/

Pagina: 1