• Welcome to Valhalla Legends Archive.
 

[C#]What the hell am I missing

Started by Dale, March 05, 2008, 05:48 PM

Previous topic - Next topic

Dale

i don't even know how many times (countless) times I've messed with the StreamReader and the StreamWriter classes in the System.IO span.

This time, it writes nothing to the file? am I just tired and overlooking a small thing? or is this my computer bugging out now?


using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace AITesting
{
    class Program
    {
       
        static void Main(string[] args)
        {
            StreamWriter strWriter = new StreamWriter("test.txt");
            strWriter.WriteLine("test");
        }
    }
}

K

Data isn't written to the file until you a) Flush the stream b) Close the stream (flushing any buffered data):

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace AITesting
{
    class Program
    {
       
        static void Main(string[] args)
        {
            StreamWriter strWriter = new StreamWriter("test.txt");
            strWriter.WriteLine("test");
            strWriter.Close();
        }
    }
}

Dale

Weird, before I even posted I tried that, and it still didn't work... but I just did and it worked! Very weird... But thanks K!

iago

Quote from: K on March 05, 2008, 06:01 PM
Data isn't written to the file until you a) Flush the stream b) Close the stream (flushing any buffered data):

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace AITesting
{
    class Program
    {
       
        static void Main(string[] args)
        {
            StreamWriter strWriter = new StreamWriter("test.txt");
            strWriter.WriteLine("test");
            strWriter.Close();
        }
    }
}

Shouldn't it automatically close the stream and write to the file when the program ends? I thought most languages did.

(I guess C# doesn't.. not that that's a bad thing or anything)
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


MyndFyre

It would if he was properly using the Disposable pattern:


using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace AITesting
{
    class Program
    {
       
        static void Main(string[] args)
        {
            using (StreamWriter strWriter = new StreamWriter("test.txt"))
            {
                strWriter.WriteLine("test");
            } // the using block implicitly calls Dispose() on the variable that was created within it.               
        }
    }
}

QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

Dale

Quote from: MyndFyre[vL] on March 06, 2008, 06:31 PM
It would if he was properly using the Disposable pattern:


using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace AITesting
{
    class Program
    {
       
        static void Main(string[] args)
        {
            using (StreamWriter strWriter = new StreamWriter("test.txt"))
            {
                strWriter.WriteLine("test");
            } // the using block implicitly calls Dispose() on the variable that was created within it.               
        }
    }
}



Thank you Mynd. I'm always interested in hearing the proper way of coding!  :)

iago

Quote from: MyndFyre[vL] on March 06, 2008, 06:31 PM
It would if he was properly using the Disposable pattern:


using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace AITesting
{
    class Program
    {
       
        static void Main(string[] args)
        {
            using (StreamWriter strWriter = new StreamWriter("test.txt"))
            {
                strWriter.WriteLine("test");
            } // the using block implicitly calls Dispose() on the variable that was created within it.               
        }
    }
}



That seems ewwy, and like it could get extremely messy. It also seems like it's more work than calling .close(). :)
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


MyndFyre

Quote from: iago on March 07, 2008, 03:10 PM
That seems ewwy, and like it could get extremely messy. It also seems like it's more work than calling .close(). :)
There are times where it can get messy, but using statements don't need to be nested - there can be two at the same level for a single block, for instance:


using (SqlConnection con = new SqlConnection(connectionString))
using (SqlCommand cmd = new SqlCommand("[dbo].[InsertUser]", con))
{
    // do stuff
}


The Disposable pattern is useful because:
* It provides a unified way to handle unmanaged resources.
* It prevents leaking and unnecessary allocation of unmanaged resources.  For example, underneath a Socket is a HANDLE to an operating system socket.  By not tying Close() to the same operation, I am able to reuse the HANDLE to the original socket, rather than reallocating it.
* The unmanaged resources are guaranteed to be released, because the compiler internally translates a using block into a try-finally block, in which Dispose() is called on the variable created within the using statement.  Equivalent C# code to the using block I demo'd in Dale's code would be:

StreamWriter strWriter;
try
{
    strWriter = new StreamWriter("test.txt");
    strWriter.WriteLine("test");
}
finally
{
    if (strWriter != null)
        strWriter.Dispose();
}


A finally block is an area of code that is guaranteed to be executed in the event that an exception is raised in the corresponding try block, but was unhandled (either because of no catch or a lack of a filtered catch). 

For a little more info...
As of .NET 2.0, it is recommended that operating system handles be wrapped within a CriticalFinalizerObject such as SafeHandle.  This is because, in the event that an exception is raised in the implicit finally block, some cleanup code may not be called.  In the event of a program crash, objects in the finalization queue previously would just have their memory cleared, which created the potential for OS leaks for resources such as global mutexes, GDI handles, and others.  Critical finalizer objects are guaranteed to be finalized before the program stops (a guarantee made by the CLR), ensuring that OS resources are not leaked.
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

NicoQwertyu

QuoteFor example, underneath a Socket is a HANDLE to an operating system socket.  By not tying Close() to the same operation, I am able to reuse the HANDLE to the original socket, rather than reallocating it.

Can you ellaborate on this a little more? Wouldn't you NOT want to use a using statement with a Socket just for that reason?