Valhalla Legends Archive

Programming => General Programming => .NET Platform => Topic started by: Dale on March 05, 2008, 05:48 PM

Title: [C#]What the hell am I missing
Post by: Dale on March 05, 2008, 05:48 PM
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");
        }
    }
}
Title: Re: [C#]What the hell am I missing
Post by: 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();
        }
    }
}
Title: Re: [C#]What the hell am I missing
Post by: Dale on March 05, 2008, 06:16 PM
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!
Title: Re: [C#]What the hell am I missing
Post by: iago on March 06, 2008, 05:43 PM
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)
Title: Re: [C#]What the hell am I missing
Post by: MyndFyre on March 06, 2008, 06:31 PM
It would if he was properly using the Disposable pattern (http://geekswithblogs.net/robp/archive/2008/02/03/looking-at-.net-the-disposable-pattern.aspx):


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.               
        }
    }
}

Title: Re: [C#]What the hell am I missing
Post by: Dale on March 07, 2008, 02:33 PM
Quote from: MyndFyre[vL] on March 06, 2008, 06:31 PM
It would if he was properly using the Disposable pattern (http://geekswithblogs.net/robp/archive/2008/02/03/looking-at-.net-the-disposable-pattern.aspx):


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!  :)
Title: Re: [C#]What the hell am I missing
Post by: iago on March 07, 2008, 03:10 PM
Quote from: MyndFyre[vL] on March 06, 2008, 06:31 PM
It would if he was properly using the Disposable pattern (http://geekswithblogs.net/robp/archive/2008/02/03/looking-at-.net-the-disposable-pattern.aspx):


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(). :)
Title: Re: [C#]What the hell am I missing
Post by: MyndFyre on March 07, 2008, 05:14 PM
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.
Title: Re: [C#]What the hell am I missing
Post by: NicoQwertyu on March 22, 2008, 12:31 PM
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?