Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

Writing to SD Card and using Thread.Sleep


  • Please log in to reply
8 replies to this topic

#1 Bloemhof

Bloemhof

    New Member

  • Members
  • Pip
  • 5 posts

Posted 28 March 2011 - 11:59 AM

Hi,

I have subscribed to the Netduino Forum in December 2010 and have followed all the topics with great anticipation - waiting for my N+! I eventually received it and decided to start with something simple to test (being a newbie with C#).

I have connected a potentiometer and are reading the voltage back and are also writing the value to a file on the SD.
This all seems to work great - until I add a Thread.Sleep to the while statement. The file is created but have no content (0Kb). If I remove the Thread.Sleep again - the file is there with data. Am I missing something very basic and simple?

The code below:

Regards
Albert

P.S. What a great community!

using System.Threading;
using System.IO;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoPlus;

namespace Potentiometer
{
    public class Program
    {
        public static void Main()
        {
            const double MAXVOLTAGE = 3.30;
            const int DIGITALRANGE = 1024;
            OutputPort LED = new OutputPort(Pins.ONBOARD_LED, false);
            AnalogInput POT = new AnalogInput(Pins.GPIO_PIN_A5);
            
            Directory.SetCurrentDirectory("\\SD");
            using (StreamWriter w = new StreamWriter("abc.txt"))
           
            while (true)
            {
                LED.Write(!LED.Read());
                
                int RAW = POT.Read();
                double VOLTAGE = (RAW * MAXVOLTAGE) / DIGITALRANGE;
                             
                w.WriteLine(VOLTAGE.ToString("f4"));
                
                Debug.Print(VOLTAGE.ToString("f4"));
                            
                // Thread.Sleep(100);

            }
        }

    }
}

Edited by Chris Walker, 28 March 2011 - 04:17 PM.
Added code tags


#2 Nevyn

Nevyn

    Advanced Member

  • Members
  • PipPipPip
  • 1072 posts
  • LocationNorth Yorkshire, UK

Posted 28 March 2011 - 05:31 PM

I have connected a potentiometer and are reading the voltage back and are also writing the value to a file on the SD.
This all seems to work great - until I add a Thread.Sleep to the while statement. The file is created but have no content (0Kb). If I remove the Thread.Sleep again - the file is there with data. Am I missing something very basic and simple?



Just a thought, how long are you leaving the program running? In the full blown .NET I would the system would be buffering the data and only writing the data out when the buffer is full.

Have you checked to see if there is a flush method to force a write to the SD card?

Regards,
Mark

To be or not to be = 0xFF

 

Blogging about Netduino, .NET, STM8S and STM32 and generally waffling on about life

Follow @nevynuk on Twitter


#3 Stefan

Stefan

    Moderator

  • Members
  • PipPipPip
  • 1965 posts
  • LocationBreda, the Netherlands

Posted 29 March 2011 - 01:24 PM

I would suspect that data is written into a local buffer but not yet to the SD-card indeed. Try adding w.Flush(); With your code it will also do this when the local buffer is full, but with the sleep in it that takes quite some time I suppose. Keep in mind, this is only a theory, I haven't tested it myself.
"Fact that I'm a moderator doesn't make me an expert in things." Stefan, the eternal newb!
My .NETMF projects: .NETMF Toolbox / Gadgeteer Light / Some PCB designs

#4 demonGeek

demonGeek

    Advanced Member

  • Members
  • PipPipPip
  • 42 posts
  • LocationCanada

Posted 30 March 2011 - 06:08 AM

Hi Albert,

You should always .Close() the stream to ensure that all the writes are completed. Modify the loop to collect a finite number of samples and then close the stream when the loop is done. Flushing will push the buffer to the stream but not the underlying encoder which may still contain data.

See if that cures the problem.

Also, you should really define the scope for the using statement otherwise there's no point in having it:

using (StreamWriter w = new StreamWriter("abc.txt"))
{
    ....
}

With your code structured the way it is, the using statement is redundant anyway, you may as well just declare the StreamWriter without it and let the GC take care of it when it gets disposed at the end of the method.

Hope that helps.

- Adam

#5 Corey Kosak

Corey Kosak

    Advanced Member

  • Members
  • PipPipPip
  • 276 posts
  • LocationHoboken, NJ

Posted 31 March 2011 - 02:10 AM

Also, you should really define the scope for the using statement otherwise there's no point in having it:

The scope of his using is the entire while statement that follows it. (The indentation may have been misleading in this case.) "using" is like "if" or "while" in the sense that it can be used without braces, though just as with if and while I would encourage the style of always using braces.

With your code structured the way it is, the using statement is redundant anyway, you may as well just declare the StreamWriter without it and let the GC take care of it when it gets disposed at the end of the method.

I'd like to vote against this advice for a variety of reasons. The StreamWriter object is not guaranteed to be collected at any particular time such as the end of the method (in fact, there's no particular guarantee that it will ever be collected), and even when it is collected, because StreamWriter has no finalizer, the Dispose() method won't be called anyway. As a programming practice I'd like to encourage you keep using 'using'.

#6 demonGeek

demonGeek

    Advanced Member

  • Members
  • PipPipPip
  • 42 posts
  • LocationCanada

Posted 31 March 2011 - 05:14 AM

The scope of his using is the entire while statement that follows it. (The indentation may have been misleading in this case.) "using" is like "if" or "while" in the sense that it can be used without braces, though just as with if and while I would encourage the style of always using braces.

Yes, I realized that. My point was that without explicitly defining the scope the object isn't going to get disposed any sooner than the end of the method. He mentions in his post that he's a C# newbie so I think it's quite possible that he wasn't even aware of the scope issue and I figured it was worth pointing it out.

I'd like to vote against this advice for a variety of reasons. The StreamWriter object is not guaranteed to be collected at any particular time such as the end of the method (in fact, there's no particular guarantee that it will ever be collected), and even when it is collected, because StreamWriter has no finalizer, the Dispose() method won't be called anyway. As a programming practice I'd like to encourage you keep using 'using'.

What advice? I explicitly stated: "you should really define the scope for the using statement".

I wasn't advising against the use of using at all, I was simply pointing out why a scope is necessary. My entire point was to encourage the correct and explicit use of the using statement.

Apologies if that didn't come across clearly in the original post.

#7 KodeDaemon

KodeDaemon

    Advanced Member

  • Members
  • PipPipPip
  • 63 posts

Posted 31 March 2011 - 06:20 AM

The point Corey was making was that the scope is the same in both cases.

using (StreamWriter w = new StreamWriter("abc.txt")) 
    while (true) 
    { 
        ...
    } 

using (StreamWriter w = new StreamWriter("abc.txt")) 
{
    while (true) 
    { 
        ...
    }
} 

Both cases have identical scope. One is just cleaner looking than the other.

Yes, I realized that. My point was that without explicitly defining the scope the object isn't going to get disposed any sooner than the end of the method. He mentions in his post that he's a C# newbie so I think it's quite possible that he wasn't even aware of the scope issue and I figured it was worth pointing it out.


What advice? I explicitly stated: "you should really define the scope for the using statement".

I wasn't advising against the use of using at all, I was simply pointing out why a scope is necessary. My entire point was to encourage the correct and explicit use of the using statement.

Apologies if that didn't come across clearly in the original post.



#8 Corey Kosak

Corey Kosak

    Advanced Member

  • Members
  • PipPipPip
  • 276 posts
  • LocationHoboken, NJ

Posted 31 March 2011 - 12:55 PM

What advice? I explicitly stated: "you should really define the scope for the using statement".

It wasn't really the first part of that statement I disagreed with so much as the second: "Also, you should really define the scope for the using statement otherwise there's no point in having it:"

What advice?

I refer to the item I quoted, namely "the using statement is redundant anyway, you may as well just declare the StreamWriter without it and let the GC take care of it when it gets disposed at the end of the method."

I'm sure you know what you're talking about but I do believe the above statement is worded carelessly and could mislead the newbie reader into believing one of the below
  • that the garbage collector ever calls Dispose
  • that the system takes any special action at all (such as Dispose) at the end of methods
  • that the GC would 'take care of' something, presumably that the StreamWriter would get properly flushed and closed anyway
...none of which are true

#9 Bloemhof

Bloemhof

    New Member

  • Members
  • Pip
  • 5 posts

Posted 05 April 2011 - 10:14 AM

Hi, Thank you Mark, Stefan, Adam and Corey for your feedback. All feedback is much appreciated!! Albert




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.