Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Console.Write ever fail?

I am testing my run() function to make sure it has all the correct things populated by the end of the method. I populate 4 fields from our databases, two strings, and two IEnumerable(string)'s. The idea is to print them all out for all the people I am pulling from the database.

When I only print the string fields, everything works fine. However, when I try to add the Enumerables as well, nothing prints at all. I am also printing a counter so I know the program is still running and working. Does Console ever decide to not print anything at all due to space or something else?

Here's the code that does it:

int i = 0;
foreach (Contact contact in Contact.LoadWithPredicate(getAll))
        {
                -------other code to populate fields---------

                i ++;
                Console.WriteLine(i);
                //Turn the Enumerables into strings for printing
                string firstEnumAsString = String.Join(", ", firstEnumerable.ToArray());
                string secondEnumAsString = String.Join(", ", secondEnumerable.ToArray());

                Console.WriteLine("Email: " + firstString+ ", correspondance: " + secondString+ ", PAM addresses: " + firstEnumAsString+ ", famousPeople: " + secondEnumAsString);
}

So, as my output, whenever I run the code above, I get an output like this:

1

2

Email: [email protected], correspondance: John, PAM addresses: [email protected], famousPeople: foo, bar, foo

3

4

etc

Problem is, only two people out of the total (~425) show up, the rest of the lines are just numbers. Shouldn't I at least get the strings "Email", and ", correspondence"? It seems like Console is just deciding not to do anything. And I know that the code must reach it because it prints out the integer i just before I call that Console.WriteLine().

On the other hand, whenever I just ask for the two string fields to be printed, the Console displays both fields for all 425 users, right after their corresponding integer. Does anyone know what's happening here? TIA

like image 663
Alex Chumbley Avatar asked Jul 05 '13 21:07

Alex Chumbley


2 Answers

Based on your comments, I think either your firstEnumerable or secondEnumerable objects are null. But since you did not post how you obtain these objects, I can't comment on why they are null or how to fix it.

It's okay for them to contain null entries, or even be fully empty, but they themselves cannot be null or it will throw an ArgumentNullException when you call .ToArray() on them. This corresponds with the "value cannot be null" exception message you're seeing.

The reason why it's not crashing and burning hard is because you are swallowing (and logging?) the exceptions within your iteration loop with a try/catch block that was not posted in your code sample.


I'm guessing your actual code is something like this:

foreach (Contact contact in Contact.LoadWithPredicate(getAll))
{
    try
    {
        ...

        object[] firstEnumerable = null;
        object[] secondEnumerable = null;

        //some logic gates here which under some circumstances do not 
        //assign a valid instance to firstEnumerable or secondEnumerable

        ...
        Console.WriteLine(i); //this prints every time

        //Turn the Enumerables into strings for printing
        string firstEnumAsString = String.Join(", ", firstEnumerable.ToArray()); //exception here
        string secondEnumAsString = String.Join(", ", secondEnumerable.ToArray()); //or exception here

        Console.WriteLine("Email: " + firstString+ ", correspondance: " + secondString+ ", PAM addresses: " + firstEnumAsString+ ", famousPeople: " + secondEnumAsString);
        ...
    }
    catch
    {
        //maybe some logging? maybe not?
    }
}

This will print out the i value each time. But when it attempts to create firstEnumAsString or secondEnumAsString it throws an exception and never hits your second Console.WriteLine("Email: " + ...); thus producing the output you're seeing. It's not that the Console.WriteLine is failing, it's that you're never calling it in the first place.

like image 171
Chris Sinclair Avatar answered Sep 28 '22 14:09

Chris Sinclair


If value is null, only the line terminator is written to the standard output stream. For more information about the line terminator, see the Remarks section of the WriteLine() method. - Source

On top of that, if one of the values you're trying to write to the console throw an Exception, like in the following code:

    private static string SomeVal { get { throw new Exception(); } }

    Console.WriteLine("Foo");
    Console.WriteLine("This throws an exception: " + SomeVal);

"This throws an exception:" won't be written to the console either; the entire string is just considered null. To me it looks like that's what's actually happening in your code; one of the values you're trying to write to the console is throwing an Exception, and it's handled somewhere silently. Are you running this code in a supressive try/catch clause?

You can easily figure out if that's the case by putting a breakpoint on Console.WriteLine or the trailing } and check the values of firstString, secondString and see if they're null. You can also tell whether one of the values you're trying to write threw an exception.

Also, you should consider using string.Format(string format, params object[] args) rather than concatenating with +. Makes debugging your code a lot easier, too.

like image 22
aevitas Avatar answered Sep 28 '22 15:09

aevitas