Tuesday, December 23, 2008

Fields vs. Properties

One element of C# that is very useful is the Property member.  Back in the days of C you would declare a struct and the members of that struct (the fields) were all public.  When C++ came along it gave use the concept of hiding our fields behind accessor methods, namely getters and setters.  Java continued this design.  C# introduces a new member type called the property, which makes managing your field getters and setters a little bit easier.  So where you might have Java code like:

public class MyClass
{
  private int myValue;

  public int getMyValue() { return myvalue; }
  public void setMyValue(int value) { myValue = value; }
}

Your C# code might look like this:

public class MyClass
{
  private int myValue;
  public int MyValue
  {
    get { return myValue; }
    set { myValue = value; }
  }
}

It's a subtle difference, but the IDE and language pickup on that syntax and make organizing your "function" methods seperately from your "attribute" methods much easier.  In fact, the latest version of the .NET framework includes a handy syntax feature called auto-properties which let you condense that declaration to:

public class MyClass
{
  public int MyValue { get; set; }
}

Here the private variable is auto-generated by the compiler.  The advantage to providing getters and setters, regardless of your language choice, is that you can later create a derived class that provides additional actions based on the setting or getting of the attribute.  So you might have:

public class MyClassWithSmallValues : MyClass
{
  public override int MyValue
  {
    get { return base.MyValue; }
    set 
    { 
      if ( value > 10 || value
      {
        throw new ArgumentException();
      }
      base.MyValue = value;
    }
  }
}

That example is pretty contrived, but you get the idea.

So where does that leave our old friend the public field?  It is still legal syntax to declar a public variable on your class, i.e.

public class MyClass
{
  public int MyValue;
}

At the base class level, this class would behave identically to either the Java or C# implementation above, and it saves you a bit of coding.  So why is this considered "bad practice"?  Well, as mentioned above, you are now trapped with that attribute on your class.  No matter how many levels of derivation you go, you will always have a MyValue and you have no way of reacting to request or change to that variable.  Still, there are times when this construct can be useful.  If it were bad in all cases the language maintainers would simply strip it out.  Here is a case where I find the public field to still be useful:

public class MyClass
{
  public readonly byte[] MyByteArray = new byte[4];
}

The goal in this implementation is to provide a class that has an array of bytes that is exactly 4 bytes long.  It can never be less, it can never be more.  Each element in the array always has a legal value for a byte.  The readonly keyword above is to instruct the C# compiler that this value can only be set once, and only at the time the class is created.  It can never be written to again, but it can be read.  A user of the class could change the values at each index of the array, but they could never modify the array itself.

The net result is that you save yourself from creating a lot of error catching code.  You don't have to check for the array to be too short or too long, nor for the array being null.  The property is indexable right off an instance of the class, and that without needing to create your own Collection class (which was a bear until MS introduced generics in the framework).  

The one drawback I can see to this implementation is that certain framework components will inspect class properties, but do not perform reflection to find public fields.  So where a DataGridView will data bind to all of the properties in a class automatically, it completely ignores your public fields.  That's just as well, because I don't think that control behaves properly with arrays, but it is worth mentioning.

So to all of the OO programmers of the world: do you still have a use for the public field?  Or is this a concept that can be eliminated from modern compilers?
 

Monday, December 22, 2008

Google Calendar Sync

I am giving up my BlackBerry in at work and reverting back to the use of my PDA (thus the previous posts looking for a cell phone).  As part of this process, I've been looking into different ways of keeping sync'ed, both with my work items and home items.  I tried an open source product called GMobileSync from RareEdge.  On paper it had everything I wanted - it would pull appointments from my Google Calendar and put them on my PDA calendar, and would also push appointments on my PDA to my Google Calendar.  This would allow me to use my PDA as a single source for all of my home and office appointments (and would allow my wife to easily check my availability for doctor's appointments or schedule me as away for any family related things).  Unfortunately, the execution is quite there.  The code is at version 1.3.6, and while it will update my PDA with appointments from my GCal, it won't go the other way (NullReferenceError).  I considered grabbing the code and debugging it, but I'd rather have a solution that just works out of the box.

Enter Google Calendar Sync from Google.  This application runs on the desktop rather than on the PDA, but it does 2-way synchronization between your Outlook calendar and your Google Calendar.  This is perfect, because my PDA syncs with my Outlook calendar anyway.  Now all of my work appointments show up on my Google Calendar, and all of my personal appointments show up on my Outlook calendar.

Wednesday, November 26, 2008

Vista Frustration

Vista is a well beaten dead horse.  Microsoft is embarassed of it, and is rushing to get Windows 7 out the door in the hopes that the world will forget Vista ever happened.  In the meantime, the world is largely ignoring Vista and staunchly sticking to their XP installations.  Personally, I've installed Vista on my work laptop and on my home PC, while leaving the PCs that my wife and kids use on XP.  

For the typical home user there is no compelling reason to upgrade to Vista.  There is nothing that Vista offers you that you aren't already getting from your Windows XP machine.  If you are one of those hold-outs hanging on to your Windows 95/98/Me edition machine....you could get a lot of of XP, but don't go all the way to Vista yet.

One feature that I have grown to like in Vista is the universal search on the Start button.  Hit your Windows key and you can start typing.  Type the name of the application you want to run, and it hunts down the shortcut.  Type the name of the document you want and it lists all matching files.  Type in a URL and it gives you a link to that website.  It is really handy, and I find myself missing it when I move back to an XP box.  Aside from that, the Aero interface is pretty but adds no tangible value.  You would be hard pressed to name any other Vista improvements that would compel you to switch.

What you will find are a bunch of frustrations though.  First, most of your older hardware just flat won't work.  Have a printer that is more than a couple of years old?  Won't work.  How about that scanner you've had for three years?  Nope, that won't work either.  Webcam?  No.  Grrr..  Vista will also gladly gobble up any extra memory you have around.  Remember two years ago when the whole Vista Capable effort started?  At the time, Vista was just on the horizon and PC manufacturers were selling units with the Vista Capable sticker to let you know that it would run Vista perfectly well.  Not so much.  These machines, outfitted with modest graphics cards and 1GB of memory or less, were horrible Vista platforms.  Vista gladly gobbled up that 1GB of memory for itself and then asked hungrily for me, denying the applications that you wanted to run any memory for themselves.  It consumed the majority of your hard disk, and it busied your graphics cards with moronic things to do like rendering the desktop in 3D, or animating your wallpaper.

On top of those intentional frustrations, there are also a number of unintended frustrations.  For one, you may notice that after time the Network, Sound, and Battery indicator icons in your system tray fall of the end never to be seen again.  For reasons unknown, Vista will occassionally reset the preference to display these, forcing you to find the arcane place where you can ask to have them displayed again.

One frustration I recently dealt with had to do with my CD drive and iTunes.  When iTunes installs, it installs a custom CD driver to assist in burning discs.  Unfortunately, this driver is exactly comfortable running on Vista x64.  Recent revisions of iTunes are much better, but the hangup is that if you ever decide to uninstall iTunes, your CDROM is going away with it.  You see, the custom driver doesn't uninstall properly along with iTunes, and it leaves Vista thinking that the drive is broken.  You have to perform a registry hack to get it back (documented here).

So here's some friendly advice from a geek.  If you have never owned a PC before, and you have no existing equipment that you want to run on a new PC, go ahead and purchase a PC with Vista installed.  Most PC's today with Vista installed have the necessary memory and graphics to get the job done, and you won't experience the pain of trying to get all of your old stuff to work.  If, however, you've been using a PC for more than 2 years, don't bother with Vista.  If you absolutely must buy a new PC, ask for it to be downgraded to XP, or see if you can get a refund for Vista and use the money to buy a copy of XP.  You'll save yourself a ton of frustration, and won't be missing anything.

Thursday, November 20, 2008

BeginRead Weirdness

I've run into a bit of an interesting problem with some code I'm working on.  It deals with asynchronous reads on a stream.  Here is a simplified version of the problem:

I have a network device that communicates by a TCP socket.  The client software connects to that TCP socket and issues commands.  Every command should receive a response from the device.  A new command must not be sent until the response to the last command was received.

So initially I wrote some code that looked like this:

public class Reader
{
private readonly Stream inStream;

public Reader( Stream in )
{
inStream = in;
}

public byte[] ReadResponse()
{
byte[] buffer = new byte[256]; 
inStream.Read(buffer, 0, buffer.Length);
return buffer;
}
}

This code worked just fine...as long as the device responded to my command.  Sometimes, the device wouldn't respond.  This might be because the device was unplugged before the response was sent (in which case my Read attempt would eventually return indicating the end of the stream was reached) or the device simply failed to respond to the command.

So now what I wanted was a way to deal with the device simply not responding to a command.  I needed some mechanism that would allow me to block on the read for only a little while.  A perfect place to use the asynchronous read!  So I modified my code to this:

public byte[] ReadResponse()
{
byte[] buffer = new byte[256]; 
IAsyncResult waitHandle 
= inStream.BeginRead(
buffer, 
0, 
buffer.Length, 
null, 
null);
bool waitResult 
= waitHandle.AsyncWaitHandle.WaitOne(
5000, 
true);
return buffer;
}

This change will read back the response if one is returned, or stop blocking after 5 seconds elapses without a response.  This works as I expected - the WaitOne returns as soon as data is available, or after the timeout period.  If the waitResult indicates that the timeout occurred, I can send my next command.  Here is where the weirdness is: the BeginRead attempting to read the response to the first command now reads the response to the second command!  This results in my latest command never receiving a response. 

So my question is, how can I block on a read for a specified period of time and avoid consuming the next byte arriving on the stream if the timeout occurs?  

I've tried a couple of things, and I have a working solution, but I'm not satisfied with it.  My current solution is to use a NetworkStream rather than a base Stream.  I would prefer to use the basic Stream type as it allows me to apply this reader to any Stream source and not just NetworkStream sources.  The NetworkStream has a DataAvailable property that returns true when data is available to be read on the stream.  I poll the DataAvailable property until data arrives or my 5 second timeout occurs.  This avoids the erroneously consumed byte.  However, in addition to the reliance on a NetworkStream source, it also introduces inefficiency as I poll the DataAvailable property.  I can either cause the CPU to spike by continuously polling the property, or I can introduce a Sleep.  The Sleep will allow the CPU usage to remain low, but also means that if the data becomes available while the thread is sleeping, I'm wasting time that could be spent processing the data.

What I really need is a way to cancel the thread that is waiting for the response asynchronously.  Unfortunately, the .NET framework doesn't support this concept.  So my only option to get this working the way I really want is to craft up my own Asynchronous read method.  Unfortunately, I can't think of a way to do this that avoids the polling scenario I have already implemented.

Saturday, October 25, 2008

Drive Space Recovery

If you are like me, when you bought your computer it had an enormous amount of hard drive space that you thought you would never fill.  As time passed and you continued to use the machine, you saw that seemingly impossibly large drive accumulate more and more cruft until one day you get the dreaded "Insufficient Disk Space" message.  Then you make a mad scramble to see just what you can delete safely and not regret later.

The article at 


is a really useful guide for folks using the Vista operating system on how to get some of that missing drive space back.  This works for Windows XP users too, although to a somewhat lesser degree.  Right click on the drive you want to cleanup, then choose properties.  The General Tab will have a button for Disk Cleanup right next to the pie showing you how little space you have left.  If you make use of all of the options in this tool, you can get a suprising amount of drive space back.  Even better, check-out the advanced cleaning options and eliminate all but your last restore point.  Restore points consume a ridiculous amount of space on your drive.

After taking advantage of the advice from that article, I managed to recover 22.3GB of hard drive space.  That's a little more than 10% of the drive!  Even better, I didn't have to make any difficult decisions about backing up or deleting music, pictures, videos, documents, or projects that I had worked on over time.