Valhalla Legends Forums Archive | .NET Platform | [C#]What the hell am I missing

AuthorMessageTime
dlStevens
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?

[code]
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");
        }
    }
}
[/code]
March 5, 2008, 11:48 PM
K
Data isn't written to the file until you a) Flush the stream b) Close the stream (flushing any buffered data):
[code]
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();
        }
    }
}[/code]
March 6, 2008, 12:01 AM
dlStevens
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!
March 6, 2008, 12:16 AM
iago
[quote author=K link=topic=17370.msg176808#msg176808 date=1204761670]
Data isn't written to the file until you a) Flush the stream b) Close the stream (flushing any buffered data):
[code]
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();
        }
    }
}[/code]
[/quote]
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)
March 6, 2008, 11:43 PM
Myndfyr
It would if he was properly using the Disposable pattern:

[code]
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.               
        }
    }
}
[/code]
March 7, 2008, 12:31 AM
dlStevens
[quote author=MyndFyre[vL] link=topic=17370.msg176841#msg176841 date=1204849891]
It would if he was properly using the Disposable pattern:

[code]
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.               
        }
    }
}
[/code]

[/quote]

Thank you Mynd. I'm always interested in hearing the proper way of coding!  :)
March 7, 2008, 8:33 PM
iago
[quote author=MyndFyre[vL] link=topic=17370.msg176841#msg176841 date=1204849891]
It would if he was properly using the Disposable pattern:

[code]
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.               
        }
    }
}
[/code]

[/quote]

That seems ewwy, and like it could get extremely messy. It also seems like it's more work than calling .close(). :)
March 7, 2008, 9:10 PM
Myndfyr
[quote author=iago link=topic=17370.msg176852#msg176852 date=1204924257]
That seems ewwy, and like it could get extremely messy. It also seems like it's more work than calling .close(). :)
[/quote]
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:

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

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:
[code]
StreamWriter strWriter;
try
{
    strWriter = new StreamWriter("test.txt");
    strWriter.WriteLine("test");
}
finally
{
    if (strWriter != null)
        strWriter.Dispose();
}
[/code]

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.
March 7, 2008, 11:14 PM
NicoQwertyu
[quote]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.[/quote]

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?
March 22, 2008, 5:31 PM

Search