ReadLine() Not Returning @ EOF - TinyCLR 2.0.0

I’m converting an old .NETMF project to a TinyCLR (version 2.0.0) {New Hardware: SCM020260D} project. I’m now testing my conversion.

There are a few functions where we read in lines from a text file (SD Card) using the StreamReader’s ReadLine() function. I’ve found that this works fine as long as ReadLine() isn’t allowed to hit the end of the file. When it is allowed to hit the end of the file it never returns, effectively halting the thread it’s working on (as if it was stuck in an infinite loop). On some debug runs I’ve even seen messages posted to the output window that seem to indicate activity within the ReadLine() function while in this state.

It’s my understanding that ReadLine() should just start returning ‘null’ once the end of file has been reached, yet no exception is indicated and the function never seems to return under these circumstances. Once I restore the file to a state where there are more than enough ‘lines’ to prevent the ReadLine() function from hitting the end of the file, everything seems to work fine. {I’ve had no problems with the WriteLine() function.}

Now, I could work around using the ReadLine() function, if need be, but it seems to me I shouldn’t have to. I’m at a loss as to why it’s acting like this though. Any ideas? To my knowledge the old .NETMF project didn’t exhibit this same problem, though the application code was the same (as it applies to this portion of it anyway).

I remember we had such issue that was fixed in the production release. Are you using the latest?

Welcome to the community.

There used to be an issue with ReadLine in NETMF 4.3 but I can’t recall what it actually was and the function below fixed this for me. I used this also with TinyCLR1.0 and will be porting the code to TinyCLR2.0 soon. Maybe this can help?

/// <summary>
/// Reads a line from the file stream
/// </summary>
/// <param name="sr"></param>
/// <returns></returns>
private static string ReadLineEx(ref StreamReader sr)
{
    int newChar = 0;
    int bufLen = 512; // NOTE: the smaller buffer size.
    char[] readLineBuff = new char[bufLen];
    int growSize = 512;
    int curPos = 0;
    while ((newChar = sr.Read()) != -1)
    {
        if (curPos == bufLen)
        {
            if ((bufLen + growSize) > 0xffff)
            {
                throw new Exception();
            }
            char[] tempBuf = new char[bufLen + growSize];
            Array.Copy(readLineBuff, 0, tempBuf, 0, bufLen);
            readLineBuff = tempBuf;
            bufLen += growSize;
        }
        readLineBuff[curPos] = (char)newChar;
        if (readLineBuff[curPos] == '\n')
        {
            return new string(readLineBuff, 0, curPos);
        }
        if (readLineBuff[curPos] == '\r')
        {
            sr.Read();
            return new string(readLineBuff, 0, curPos);
        }
        curPos++;
    }

    if (curPos == 0) return null; // Null fix.
    return new string(readLineBuff, 0, curPos);
}
1 Like

Thanks… I’m fairly sure I can work around using the normal ReadLine() function as suggested. I was just a bit confused as to why this seemed necessary, as I thought I was using the latest TinyCLR / Assembly production releases. I suppose I could be wrong though.

I just checked using the TinyCLR Configurator. The version listed at the top read 2.0.0.8000 (I assume that is the version of the TinyCLR?) Performing a reboot and looking in the Debug window all the TinyCLR assemblies are listed as 2.0.0.0. Do these version numbers have to match? I assumed they need not match perfectly and I don’t seem to be getting any deployment errors when debugging.

Does this help in determining whether I’m using the latest production release? Or do you need something else?