Skip to main content

.NET 4 Baby Steps - Part X: Location, Location, Location

Note: This post is part of a series and you can find the rest of the parts in the series index.

This is seriously some of the coolest stuff in .NET 4: System.Device.Location which gives you access to the Windows 7 sensor platform to build location aware applications. The two important classes to know are:

  • GeoCoordinateWatcher: Think of this as your GPS device. It gives you time and latitude and longitude.
  • CivicAddressResolver: This translates latitudes and longitude into addresses!

Usage

Usage of it is very easy. First we create a resolver and gps and then we tell the GPS to start. We assign an event to alert us when the position has changed and when we done we tell the GPS to stop.

static System.Device.Location.CivicAddressResolver resolver = new System.Device.Location.CivicAddressResolver();
static System.Device.Location.GeoCoordinateWatcher gps;

static void Main(string[] args)
{
    Console.Clear();
    Console.WriteLine("Press any key to quit");

    using (gps = new System.Device.Location.GeoCoordinateWatcher())
    {
        gps.PositionChanged += new EventHandler<System.Device.Location.GeoPositionChangedEventArgs<System.Device.Location.GeoCoordinate>>(gps_PositionChanged);
        
        gps.Start();                

        Console.ReadKey();

        gps.Stop();
    }
}

When the GPS position changes we write it to the screen as follows:

static void gps_PositionChanged(object sender, System.Device.Location.GeoPositionChangedEventArgs<System.Device.Location.GeoCoordinate> e)
{
    Console.Clear();
    Console.WriteLine("Last updated at: {0}", DateTime.Now);
    Console.WriteLine("Your location: {0}", e.Position.Location);
    Console.WriteLine("I think that is: {0}", NiceAddress(e.Position.Location));
    Console.WriteLine("Press any key to quit");
}

How do we get our address and display it nicely?

private static object NiceAddress(System.Device.Location.GeoCoordinate geoCoordinate)
{
    System.Device.Location.CivicAddress address = resolver.ResolveAddress(geoCoordinate);
    if (address.IsUnknown)
    {
        return "Unknown";
    }

    return string.Join("\n", address.FloorLevel, address.Building, address.AddressLine1, address.AddressLine2, address.City, address.StateProvince, address.CountryRegion, address.PostalCode);
}

And all this code produces the following:

image

Distances?

The GeoCoordinate class has a brilliant method called GetDistanceTo which returns the distance, in meters (Metric system FTW) between it and another GeoCoordinate. So for me to find the distance to the Lions Rugby Team home stadium I just do:

static void gps_PositionChanged(object sender, System.Device.Location.GeoPositionChangedEventArgs<System.Device.Location.GeoCoordinate> e)
{
    Console.Clear();
    Console.WriteLine("Last updated at: {0}", DateTime.Now);
    System.Device.Location.GeoCoordinate ellisPark = new System.Device.Location.GeoCoordinate(-26.1978417421848, 28.060884475708 );
    Console.WriteLine("It is {0}km to Ellis Park", e.Position.Location.GetDistanceTo(ellisPark) / 1000);
    Console.WriteLine("Press any key to quit");
}

Which gives:

image

Accuracy?

The accuracy can be controlled in settings, but a lot of it is up to your GPS receiver device. Unfortunately I do not have a proper hardware based GPS device, so I have used the excellent free software based Geosense for Windows, which you can see is accurate enough for most scenarios.

No sensor?

If you are on a version of Windows prior to 7, then the status of the GPS sensor will be set to Disabled.

If you are on Windows 7 without a GPS sensor then when you run it, you will be prompted for your default location information which Windows can try and use to find you.

image

Mobile?

As a bonus to using this, it is similar as the geolocation system in the new Windows Phone 7 platform! You can find out about geolocation in Windows Mobile 7 in Rudi’s blog post.

.NET 4 Baby Steps: Part IX - Stream

Note: This post is part of a series and you can find the rest of the parts in the series index.

Streams are something I try to avoid, it feels to me like I am getting down and dirty when I use them – but maybe that is just flash backs to working in Delphi :) They are very useful, but they can be clunky especially when you need to get the content into another stream.

The key example of coping a steam is when you write your own file copy method (and which programmer hasn’t):

using (FileStream sourceFile = new FileStream("test.xml", FileMode.Open))
{
    using (FileStream destinationFile = new FileStream("target.xml", FileMode.Create))
    {
        byte[] buffer = new byte[4096];
        int read;
        while ((read = sourceFile.Read(buffer, 0, buffer.Length)) != 0)
        {
            destinationFile.Write(buffer, 0, read);
        }
    }
}

The whole buffer/read/write pattern is just ugly.

Now with .NET 4, we can use the new CopyTo method to fix this up:

using (FileStream sourceFile = new FileStream("test.xml", FileMode.Open))
{
    using (FileStream destinationFile = new FileStream("target.xml", FileMode.Create))
    {
        sourceFile.CopyTo(destinationFile);
    }
}

Ah, much better!

.NET 4 Baby Steps: Part VIII - Enumerate Directories and Files

 cael Note: This post is part of a series and you can find the rest of the parts in the series index.

.NET 4 has seven (!!) new methods for enumeration of directories, files and contents of files. What makes these stand apart from what we have had before, is these return IEnumerable<T> rather than arrays.

Why is it better to get IEnumerable<T> over an array? Rather than getting all the data into one structure first, the array, and returning a massive lump of data. With IEnumerable<T> it returns it one item at a time, as it enumerates that item. If this doesn’t make sense, see the example below.

Example

Old way

So in this example I use the old method:

DirectoryInfo root = new DirectoryInfo(@"c:\");

var collection = from f in root.GetFiles("*", SearchOption.AllDirectories)
                 select f;

foreach (var item in collection)
{
    Console.WriteLine(item);
}

However due to some permissions it will fail with an exception. Note where the exception is, it is where we are asking for the files and the the console output at this point is empty because it hasn’t finished loading all the data into the array.

image

New Way

Now we change it to the new method:

DirectoryInfo root = new DirectoryInfo(@"c:\");

var collection = from f in root.EnumerateFiles("*", SearchOption.AllDirectories)
                 select f;

foreach (var item in collection)
{
    Console.WriteLine(item);
}
This time see how the exception occurred during the iteration of the items and note how the output contains some files now, because it has processed those already.

image

This is a major advantage of the new IEnumerable<T> versions, because now we do not need to wait for all items to be found first and that means it is easier to do high performance code and threading.

What are the new methods?

The seven methods are:

  • Directory.EnumerateDirectories
    • This returns IEnumerable<string> of the folder names.
  • DirectoryInfo.EnumerateDirectories
    • This returns IEnumerable<DirectoryInfo>.
  • Directory.EnumerateFiles
    • This returns IEnumerable<string> of the files fullname.
  • DirectoryInfo.EnumerateFiles
    • This returns IEnumerable<FileInfo>.
  • Directory.EnumerateFileSystemEntries
    • This returns IEnumerable<string> of the file system entries.
  • DirectoryInfo.EnumerateFileSystemEntries
    • This returns IEnumerable<FileSystemInfo>.
  • File.ReadLines
    • This returns IEnumerable<string> where each string is a line from text file.

.NET Baby Steps: Part VII - Caching

Photo296 Note: This post is part of a series and you can find the rest of the parts in the series index.

.NET has had one out of the box way to do caching in the past, System.Web.Caching. While a good system it suffered from two issues. Firstly it was not extensible, so if you wanted to cache to disk or SQL or anywhere other than memory you were out of luck and secondly it was part of ASP.NET and while you could use it in WinForms it took a bit of juggling.

The patterns & practises team saw these issues and have provided a caching application block in their Enterprise Library which has been used by everyone who did not want to re-invent the wheel. Thankfully from .NET 4 there is a caching system now included in the framework which solves those two issues above. This is known as System.Runtime.Caching.

Slow Example

To see how to use it lets start with a process which we can cache. I have a class called Demo which has a property named Times which is of type IEnumerable<DateTime>. To set the value of Times, you call the SetTimes method and that populates the property with 5 values. However there is a delay of 500ms between each adding of DateTime to the Times property, so it takes 2.5secs to run. In my Program class I have a method, PrintTimes which creates a new Demo object, calls SetTimes and then prints the value to screen. Lastly I in my Main method I call PrintTimes three times – in total it takes 7.5secs to run.

class Program
    {
        public static void Main()
        {
            PrintTimes();
            PrintTimes();
            PrintTimes();
        }

        private static void PrintTimes()
        {
            Demo demo = new Demo();            
            Stopwatch stopwatch = Stopwatch.StartNew();
            demo.SetTimes();
            foreach (DateTime time in demo.Times)
            {
                Console.WriteLine(time);
            }
            stopwatch.Stop();
            Console.WriteLine("It took {0} to print out the times", stopwatch.ElapsedMilliseconds);
        }
    }

    class Demo
    {
        public List<DateTime> Times { get; set; }

        public void SetTimes()
        {

            if (Times == null)
            {
                Times = new List<DateTime>();
                for (int counter = 0; counter < 5; counter++)
                {
                    Thread.Sleep(500);
                    Times.Add(DateTime.Now);
                }
            }

        }
    }

The output is from this example code is below. Note the times printed are constantly changing and that it takes ~2500ms to print out each set of values.

 image

Cache Example

Now I change the PrintTimes method to incorporate the caching by creating an ObjectCache which I set to use the default MemoryCache instance. I can check if the cache contains an object using the .Contains method, I retrieve from the cache using the .Get method and I add to the cache using the .Add method:

private static void PrintTimes()
{
    Demo demo;

    Stopwatch stopwatch = Stopwatch.StartNew();
    
    ObjectCache cache = MemoryCache.Default;
    if (cache.Contains("demo"))
    {
        demo = (Demo)cache.Get("demo");
    }
    else
    {
        demo = new Demo();
        demo.SetTimes();
        cache.Add("demo", demo, new CacheItemPolicy());
    }

    foreach (DateTime time in demo.Times)
    {
        Console.WriteLine(time);
    }
    stopwatch.Stop();
    Console.WriteLine("It took {0} to print out the times", stopwatch.ElapsedMilliseconds);
}

This gives the output:

 image

Note the time to print out for the first one is about 60ms longer but the second two is down to 0ms and also note how the values in the three sets in are the same.

CacheItemPolicy

In the above example I just use a default CacheItemPolicy, but you could do a lot more with the CacheItemPolicy:

  • AbsoluteExpiration: Set a date/time when to remove the item from the cache.
  • ChangeMonitors: Allows the cache to become invalid when a file or database change occurs.
  • Priority: Allows you to state that the item should never be removed.
  • SlidingExpiration: Allows you to set a relative time to remove the item from cache.
  • UpdateCallback & RemovedCallback: Two events to get notification when an item is removed from cache. UpdateCallback is called before an item is removed and RemovedCallBack is called after an item is removed.

Things to watch out for

  • .NET 4 only ships with support for memory caching out of the box, so you will need to build your own provider if you want any other cache source.
  • You must add the System.Runtime.Caching.dll reference to get access to the namespace and classes.
  • This is NOT part of the .NET 4 client profile, it is only in the full .NET 4 Framework. I have logged an issue with Connect to move the assembly into the client profile and if you agree with this idea, please vote on it: 558309

.NET 4 Baby Steps: Part VI - SortedSet

Note: This post is part of a series and you can find the rest of the parts in the series index.

SortedSet<T> provides a way to have a sorted list of items, which is sorted internally in a binary tree. This is different to the index  based sorting on SortedList<T, K> or SortedDictionary<T, K>. This means that inserts and edits to the tree are done with almost no perf impact and it also means we do not need to figure out the key manually. Without an index, you may ask how does it know the sort order? The answer is that the class it is using must implement IComparable so it can sort correctly:

Usage is very simple:

public static void Main()
{
    Random random = new Random();
    SortedSet<GPSPosition> gpsPositions = new SortedSet<GPSPosition>();
    for (int counter = 0; counter < 100000; counter++)
    {
        gpsPositions.Add(new GPSPosition(random.Next(-180, 181), random.Next(-180, 181)));
    }

    foreach (GPSPosition position in gpsPositions)
    {
        Console.WriteLine(position);
    }
}

Note: I am using the same GPSPosition class from part IV. This gives the following output:

image

ISet<T>

Under the surface SortedSet<T> implements the new ISet<T> interface, which is especially designed for collections with unique items. HashedSet<T>, which was introduced in 3.5, has also been updated to implement ISet<T>.

.NET 4 Baby Steps: Part V - Lazy

12122009025Note: This post is part of a series and you can find the rest of the parts in the series index.

Lazy<T> is a new class which has been added to cater for scenarios where

  • you may need to create an object early.
  • the creation is expensive (CPU, memory) or slow.
  • you may not need the data the object provides when you do the creation of the object.

An example of this is LINQ which does not actually execute the query when you define it. Execution of the LINQ query occurs only when you ask for the data or some calculation on the data (like .Count()). It is done this way to prevent slow or expensive (memory, CPU) operations from being called if they are not needed.

Lazy<T> allows you to assign an object, but not actually create it until needed. Example of usage:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Before assignment");
        Lazy<Slow> slow = new Lazy<Slow>();
        Console.WriteLine("After assignment");

        Thread.Sleep(1000);
        Console.WriteLine(slow);
        Console.WriteLine(slow.Value);
    }
}

class Slow
{
    public Slow()
    {
        Console.WriteLine("Start creation");
        Thread.Sleep(1000);
        Console.WriteLine("End creation");
    }
}

Which produces a result of:

image

See how the start creation line is only after the assignment when we actually ask for the value. Methods on the object work the same, the first time you call a method it then does the creation.

Forth Coming Attraction: Brian Noyes speaking

Brian Noyes will be in South Africa next week and for one night only he will be giving a free presentation on MVVM at Microsoft’s offices in Bryanston. Brian works at IDesign and is a Connected Systems MVP and is known for being one of the top Silverlight/WPF/WCF/WF experts and so if you interested in those technologies or the MVVM pattern then this is must attend!

Details:

.NET 4 Baby Steps: Part IV - Observer

13042010196Note: This post is part of a series and you can find the rest of the parts in the series index.

The pub/sub pattern is a simple concept, you have a provider which has data which it pushes to subscribers and .NET 4 brings in two new interfaces IObservable<T> and IObserver<T> which make implementing this pattern very easy.

To see the usage of these interfaces, I would like to use the example of a device which has a GPS sensor which every second checks it’s position and if the position of the GPS leaves a specified area we then want to notify the cops.

GPSPosition

First we need a small class which tells us where we are, i.e. it is just a data class. Some key points of this class are

  • I have implemented IComparable so I can check when the boundary is exceeded.
  • I’ve overridden ToString so it prints nicely.
  • I have two constructors, a default and one which takes a latitude and longitude so that I can copy the values from one object to another.
  • Note that my parameter is named @long – because long is a reserved keyword in C# you can append @ to use it.
class GPSPosition : IComparable<GPSPosition>
{
    public int Lat { get; set; }
    public int Long { get; set; }

    public GPSPosition() { }

    public GPSPosition(int lat, int @long)
    {
        this.Lat = lat;
        this.Long = @long;
    }

    public override string ToString()
    {
        return string.Format("Latitude = {0:N4}, Longitude = {1:N4}", Lat, Long);
    }
    
    public int CompareTo(GPSPosition other)
    {
        if (this.Lat > other.Lat)
        {
            return 1;
        }

        if (this.Lat < other.Lat)
        {
            return -1;
        }

        // latitude is the same

        if (this.Long > other.Long)
        {
            return 1;
        }

        if (this.Long < other.Long)
        {
            return -1;
        }

        // long is the same
        return 0;
    }     
}

GPSSensor

Now we need to create our fake sensor, which when asked tells us where in the world we are. Key points here are:

  • It implements IObservable<T> so it is a provider of GPSPosition data. That means we needed to implement the subscribe method so other objects can tell this class to send them the data.
  • We keep a list of the observers in a List<T>
  • We call the observer.OnNext to send data to it.
  • We call observer.OnCompleted when we are done with monitoring, which in our example is when we exceed the boundary.
  • Note that in the GetPosition method we are responsible for sending data to all the observers.
class GPSSensor : IObservable<GPSPosition>
{
    List<IObserver<GPSPosition>> observers = new List<IObserver<GPSPosition>>();
    Random random = new Random();
    public GPSPosition Position { get; set; }

    private GPSPosition boundry;

    public GPSSensor()
    {
        this.Position = new GPSPosition();
        this.Position.Lat = random.Next(0, 181);
        this.Position.Lat = random.Next(0, 181);

        boundry = new GPSPosition(this.Position.Lat + 10, this.Position.Long + 10);
    }

    public void GetPosition()
    {
        GPSPosition current = new GPSPosition(this.Position.Lat, this.Position.Long);

        Position.Lat += random.Next(0, 5);
        Position.Long += random.Next(0, 5);

        if (current.CompareTo(this.Position) != 0)
        {
            foreach (IObserver<GPSPosition> observer in observers)
            {
                observer.OnNext(this.Position);
                if (current.CompareTo(boundry) > 0)
                {
                    observer.OnCompleted();
                }
            }
        }
    }


    public IDisposable Subscribe(IObserver<GPSPosition> observer)
    {
        observers.Add(observer);
        observer.OnNext(this.Position);
        return observer as IDisposable;
    }
}

Map

Our third class, Map is a subscriber of data and it handles the outputting to the screen and notification of the cops when we move past the boundary. Key notes here:

  • It implements IObserver<GPSPosition> so it is a subscriber of GPS position data.
  • We implement the three methods from the interface:
    • OnCompleted for when we are done.
    • OnError in case something goes wrong.
    • OnNext for when new data is available.
class Map : IObserver<GPSPosition>
{
    private GPSPosition lastKnown;

    public bool StillTracking { get; private set; }

    public void OnCompleted()
    {
        Console.WriteLine("The device has moved beyond the boundsof our checking, notify the cops it was last seen at: {0}", lastKnown);
        StillTracking = false;
    }

    public void OnError(Exception error)
    {
        Console.WriteLine("SkyNet has taken over and shut down the GPS");
    }

    public void OnNext(GPSPosition value)
    {
        lastKnown = value;
        Console.WriteLine("At {0} we have moved to {1}", DateTime.Now, value);
        StillTracking = true;
    }
}

Main

We have created our data structure, our provider and and our subscriber - now we just need to bring them together in our main method, which is very easy:

public static void Main()
{
    GPSSensor sensor = new GPSSensor();
    Map map = new Map();
    sensor.Subscribe(map);
    do
    {
        sensor.GetPosition();
        Thread.Sleep(1000);
    } while (map.StillTracking);
}

This produces something that looks like:

image

.NET 4 Baby Steps: Part III - Enum

Photo318Note: This post is part of a series and you can find the rest of the parts in the series index.

Enumerations are something I have posted about before because they are very useful and with .NET 4 they have had two new methods added which could have been ripped from my personal feature requests:

HasFlag

Enums can be bitwise values if the Flag attribute is set, however checking the bitwise values was ugly and very confusing for people who hadn’t seen it before. For example:

[Flags]
enum CupboardContents
{
    Nothing = 0,
    Cups = 1,
    Plates = 2,
    Cuttlery = 4,
    Food = 8,
    DeadBodies = 16,
    Everything = Nothing | Cups | Plates | Cuttlery | Food | DeadBodies
}

static void Main(string[] args)
{
    CupboardContents motherHubberbs = CupboardContents.Nothing;
    CupboardContents normal = CupboardContents.Plates | CupboardContents.Cups | CupboardContents.Cuttlery;
    CupboardContents hitman = CupboardContents.DeadBodies;
    CupboardContents bursting = CupboardContents.Everything;

    CupboardContents test = CupboardContents.Plates;

    Console.WriteLine("Does {0} contain {1} = {2}", motherHubberbs, test, (motherHubberbs & test) == test);
    Console.WriteLine("Does {0} contain {1} = {2}", normal, test, (normal & test) == test);
    Console.WriteLine("Does {0} contain {1} = {2}", hitman, test, (hitman & test) == test);
    Console.WriteLine("Does {0} contain {1} = {2}", bursting, test, (bursting & test) == test);
}

This produces image

With .NET 4 we now we get a simple method to do this check, HasFlag, which takes an enum and tells you if that is set. The following code does the same as the code above:

Console.WriteLine("Does {0} contain {1} = {2}", motherHubberbs, test, motherHubberbs.HasFlag(test));
Console.WriteLine("Does {0} contain {1} = {2}", normal, test, normal.HasFlag(test));
Console.WriteLine("Does {0} contain {1} = {2}", hitman, test, hitman.HasFlag(test));
Console.WriteLine("Does {0} contain {1} = {2}", bursting, test, bursting.HasFlag(test));

TryParse

Until now the only way to get from a string to an enum has been the Parse method:

enum Colours
{
    Red,
    Green,
    Blue
}

static void Main(string[] args)
{
    Colours red = (Colours)Enum.Parse(typeof(Colours), "Red");

    Console.WriteLine(red);
}
Which produces image

However get the string wrong and you were forced to deal with an ArgumentException:

image

With .NET 4, you now can use TryParse method and check the returned value first to see if the conversion was successful:

enum Colours
{
    Red,
    Green,
    Blue
}

static void Main(string[] args)
{
    Colours red;
    Colours purple;
    if (Enum.TryParse("Red", out red))
    {
        Console.WriteLine(red);
    }
    else
    {
        Console.WriteLine("Could not translate to a valid enum");
    }

    if (Enum.TryParse("Purple", out purple))
    {
        Console.WriteLine(purple);
    }
    else
    {
        Console.WriteLine("Could not translate to a valid enum");
    }
}

Which produces: image

Another benefit of this method over Parse is that it works with generics and that means you do not need to pass the Type parameter in and cast the return value as you had to do with Parse!

.NET 4 Baby Steps: Part II - String

Photo-0046 Note: This post is part of a series and you can find the rest of the parts in the series index.

I would guess strings are the most used type in .NET, so it is great to see some small improvements with them in .NET 4.

IsNullOrWhiteSpace

Since .NET 2.0 we have had the very useful IsNullOrEmpty which let us check for empty strings, but what about strings that contained nothing but white space? Unfortunately that would not be identified as empty! With .NET 4 we have a new method, IsNullOrWhiteSpace, which checks if a string is null, empty and if it is not just white space! Example usage:

string nullString = null;
string emptyString = string.Empty;
string blankString = emptyString.PadRight(30, ' ');
string notBlankString = "SADev.co.za";

Console.WriteLine("IsNullOrEmpty");
Console.WriteLine("\t nullString is: {0}", string.IsNullOrEmpty(nullString));
Console.WriteLine("\t emptyString is: {0}", string.IsNullOrEmpty(emptyString));
Console.WriteLine("\t blankString is: {0}", string.IsNullOrEmpty(blankString));
Console.WriteLine("\t notBlankString is: {0}", string.IsNullOrEmpty(notBlankString));

Console.WriteLine("IsNullOrWhiteSpace");
Console.WriteLine("\t nullString is: {0}", string.IsNullOrWhiteSpace(nullString));
Console.WriteLine("\t emptyString is: {0}", string.IsNullOrWhiteSpace(emptyString));
Console.WriteLine("\t blankString is: {0}", string.IsNullOrWhiteSpace(blankString));
Console.WriteLine("\t notBlankString is: {0}", string.IsNullOrWhiteSpace(notBlankString));

This produces

 image

The important one to note is blankString, in the second set (line 15 of the code) has a different result compared to it’s result in the first set.

Join & Concat

Join allows us to concatenate an array of strings together with a specific separator character in place. For example:

string[] someValues = { "This", "is", "a", "list", "of", "strings" };
Console.WriteLine(string.Join(Environment.NewLine,someValues));

This produces

image

Concat does the same thing, except there is no separate character. Example:

string[] someValues = { "This", "is", "a", "list", "of", "strings" };
Console.WriteLine(string.Concat(someValues));

This produces:

image

Both these methods fails when we start working with generic lists, like List<T> as they were not supported. This meant you often ended up calling .ToArray on the list and taking the performance impact. Now new overloads have been added to string which cater for IEnumerable<T> so we no longer need to ToArray the list. Now we can pass the list directly in, as in the following example:

List<string> someValues = new List<string>() { "This", "is", "a", "list", "of", "strings" };
Console.WriteLine(string.Join(Environment.NewLine, someValues));