Apr 17 2012

Compiling Same Code on Windows Phone 7 and Windows 8 Metro

Category: Desktop and Server | MobileJoel Ivory Johnson @ 12:27
Download Code (1.14 MB)

I was thinking about how to write code that will work on both Windows Phone 7 and Windows 8 (Metro). In theory some of the techniques that could be used are well known. But I wanted to try them out. So I decided to try some things out in a piece of throw away code. This gives me some liberty to experiement without worrying about the long term consequences of having not chosen the "best" way. For my throw away application I decided to make an application that would grab some one's Facebook friend list and display it on the screen. So this code will necessarily need to authenticate the user against Facebook. If you've not worked with the Facebook APIs before don't worry about it too much. You should still be able to follow along since this isn't digging deeply into what's available.

I've managed to use some of the techniques to make a Windows Metro version of RestSharp. I'll talk about that in another post.

Register your Application

Before you begin doing any coding you'll want to register your new Facebook application in the Facebook developer portal. This also means that you need to have a facebook account. Because I didn't want to bother my associates with test items in my feed I also created a secondaty facebook account for testing. The portal is available at developer.facebook.com. Clicking on menu item "Apps" at the top of the screen will take you to a page that shows all of your registered applications (if any) and will let you register more. If this is your first time using the portal you'll have no applications. I'll walk you through registering an application. I'll only draw your attention to options as necessary. Options that I don't mention can be left in their default state (which will most likely be blank).

Click on the "Create New App" button. You'll get prompted with a dialog in which you will need to enter the name of the application that you are creating. The dialog will automatically validate the name that you've entered once you've stopped typing and will let you know if a chane needs to be made. Once you have a name that the dialog considers valid click on the "Continue" button.

The next dialog is a Captcha. I really dislike Captchas. While I understand that these dialogs exists to make sure that a bot is not registering the new application the problem that I have with them is that more times than not I'm going to get the entry wrong a few times (ex: is that third character a lowercase 'L', upper case 'L', or an uppercase 'I'?).

Once you pass the Captcha you'll get an opportunity to specify the other details for your application and a chance to change the application's icon and category. It may not be obvious which option to select for "Select how your app integrates with Facebook." None of the available options has a description that you would automatically assocate with a Windows Phone or Metro application. Select "Website". During development it doesn't matter if the website that you've specified exists or not. But you will need to enter an address to a page that would  in theory process the login information. Once you've entered this information select "Save Changes." There are three pieces of information that are on this page that you'll be copying into your application later on: App ID, App Secret, and the Site URL. Keep this page open so that you can copy the information when I refer to it later.

 

 

Now to make your mobile application. At the time of this writing you'll need to use Visual 2010 for Windows Phone applications and Visual Studio 11 for Windows Metro applications. Most of what will be done will be similar enough such that I can talk about the procedure to be followind in parallel and note the occasional differences as they arise.

Creating the New Application Projects

I created both a Silverlight Application for Windows Phone and a Windows 8 Metro project. There are going to be significant blocks of code that will be identical between these two projects. When this occurs I'll only create one version of the file but will have it referenced in both projects. Linked files can easily be recognized by the arrow that shows in the lower-left corner of their icon. If you've never linked files before you can find more information on it here.

How linked files appear in Visual Studio.

Conditionally Compiled Code

There still may be sections in thee files that are specific to Windows Phone or Windows 8. These sections will be conditionally commented out depending on the platform on which the code is being compiled. For code that is specific to Windows 8 Metro applications the code is wrapped in #if NETFX_CORE/#endif blocks. For Windows 7 code I've wrapped the code in #if SILVERLIGHT/#endif blocks. I could have also used #if WINDIWS_PHONE/#endif blocks

If there is a large block of code that is specific to one platform and not the other instead of using the conditional compilation directives one could choose to just include the file containing the code in one file and not in the other. You'll see this done with most of the UI code (the XAML, while similar, is not shared between the two projects).

Creating the Authentication Page

Before I can call any method in Facebook I need to authenticate the user. Facebook uses a form of open authentication. So we will need to use a web browser in the application. Add a new page to your project caled "AuthenticationPage.xaml." The only element that is necessary in this page will be the web browser.  Many of the differences that you will encounter between Metro and Windows Phone 7 are in UI related code. There's a slight difference in the element that needs to be used for representing a browser element.

 <WebView 
     x:Name="AuthenticationWindow" 
     HorizontalAlignment="Stretch" 
     VerticalAlignment="Stretch"
     LoadCompleted="AuthenticationWindow_LoadCompleted" 
/>
 
<phone:WebBrowser  
   Name="AuthenticationWindow" 
   HorizontalAlignment="Stretch"
   VerticalAlignment="Stretch" 
   Navigated="AuthenticationWindow_Navigated" 
/>
Browser element for Windows Metro
 
Browser element for Windows Phone 7

The Application Constants

There are a few elements of data to which we will need. They are all in the entries for the app that you registered with Facebook. I'll need to use these in more than one place. The logic needed for authentication is simple and I left it in the UI code.  I separated the logic that will be shared in the Metro and WP7 versions of this application into a partial class definition. That

static class ApplicationConstants
{
	const string REDIRECT_URL = "https://mysite.com/SomePostAuthenticationPage.html";
	const string APP_ID = "_YOUR_APP_ID_";
	const string APP_SECRET = "_YOUR_APP_SECRET_";
	const string PERMISSIONS = "read_friendlists";
}

You'll need to substitute the values for your own application in these constants (except for the PERMISSIONS constant).

Creating the Authentication Page

An extremely high level overview of what occurs in the code-behind for the authentication page is that it will load the Facebook Open Authentication page and then monitor the path to which the user navigates. If the user has authenticated the browser will be directed to the site that had been registered for the application earlier. When this occurs there will be an authentication code appended to the URL. That code will be parsed out and exchanged for a token. There's not much the UI is really doing. So the codebehind looks simple. 

public partial class AuthenticationPage : PhoneApplicationPage
{
   public AuthenticationPage()
   {
      InitializeComponent();
      ViewModel = (App.Current as J2i.Net.FacebookAuthenticationTest.App).ViewModel;
      ViewModel.AuthenticationAttempted = true;
   }

   private void AuthenticationWindow_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
   {
   }

   private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
   {  
      PrepareForAuthentication();
   }

   private void AuthenticationWindow_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
   {
   }

   private void AuthenticationWindow_Navigating(object sender, NavigatingEventArgs e)
   {
      ProcessWebPageLoad(e.Uri.ToString());
   }
}
Code-behind for the Windows Phone version of the application

Handling Code Differences with Partial Classes

Where there is a slight difference in the code behind for the two pages the rest of the logic is the same. Instead of duplicating it I put the common logic in a partial class definition. The partial class has the same name as the class for the page. So at compile time the code from the code-behind and the partial class will be compiled into a single class. The common code is in AuthenticationPage.xaml.shared.cs.  The first method that the code-behind references from the shared file is PrepareForAuthentication(). This method will build the authentication URL which contains parameters to allow the application to identify itself, what permissions are needed, and a random string that should be passed for security reasone. If you want to see more information on these parameters they can be found in the Facebook authentication documentation.

void PrepareForAuthentication()
{
    _unique = Guid.NewGuid().ToString();

    string targetUrl = String.Format("https://www.facebook.com/dialog/oauth?" +
                                        "client_id={0}" +
                                        "&redirect_uri={1}" +
                                        "&scope={2}" +
                                        "&state={3}",
                                        // for touch/phone friendly version of the authentication page
                                        //"&display=touch",
                                        Uri.EscapeUriString(ApplicationConstants.APP_ID),
                                        Uri.EscapeUriString(ApplicationConstants.REDIRECT_URL),
                                        Uri.EscapeUriString(ApplicationConstants.PERMISSIONS),
                                        Uri.EscapeUriString(_unique));
    AuthenticationWindow.Navigate(new Uri(targetUrl));
}

The ProcessWebPage() method looks at the URL to which the browser is navigating to see whether or not it is our redirect URL. If it's not then nothing happens. If it is then the query parameters are extracted. Theparameters we are most interested in are code and state since these will indicate a successful authentication attempt. The code will be needed to request an access token for making Facebook API calls.

void ProcessWebPageLoad(string targetUriString)
{
   if (targetUriString.IndexOf(ApplicationConstants.REDIRECT_URL) == 0)
   {

      string _code = GetQueryParam(targetUriString, "code");
      string _state = GetQueryParam(targetUriString, "state");
      string _error = GetQueryParam(targetUriString, "error");
      string _errorReason = GetQueryParam(targetUriString, "error_description");
      string _errorDescription = GetQueryParam(targetUriString, "error_reason");

      if (
         (!String.IsNullOrEmpty(_code)) &&
         (!String.IsNullOrEmpty(_state)) &&
         (_unique.Equals(_state))
      )
      {
         ExchangeCodeForAccessToken(_code);
      }
   }
}

Requessting the access token is another web call, but it's not one for which we need the browser. It doesn't return anything user friendly so we can make the call without using the browser. Getting the access token is just a matter of building a URL and grabbing the token from the results.

void ExchangeCodeForAccessToken(string code)
{
    //Building the Request URL
    string targetUrl = String.Format("https://graph.facebook.com/oauth/access_token?" +
                                        "client_id={0}" +
                                        "&redirect_uri={1}" +
                                        "&client_secret={2}" +
                                        "&code={3}",
                                        Uri.EscapeUriString(ApplicationConstants.APP_ID),
                                        Uri.EscapeUriString(ApplicationConstants.REDIRECT_URL),
                                        Uri.EscapeUriString(ApplicationConstants.APP_SECRET),
                                        Uri.EscapeUriString(code));
    var webRequest = HttpWebRequest.CreateHttp(targetUrl);

    //Request the URL
    webRequest.BeginGetResponse((o) =>
    {
        //Stuff the response into a string
        var response = webRequest.EndGetResponse(o);
        var rs = response.GetResponseStream();
        StreamReader sr = new StreamReader(rs);
        var responseString = sr.ReadToEnd();

        //Get the access token and its expiration date
        string accessToken = GetQueryParam(responseString,"access_token");
        DateTime expirationDate = DateTime.MinValue;
        string expiresString = GetQueryParam(responseString, "expires");

        if (!String.IsNullOrEmpty(expiresString))
        {
            int expireTime;
            if (int.TryParse(expiresString, out expireTime))
            {
                expirationDate = DateTime.Now.AddSeconds(expireTime);
            }
        }

        //If we successfully got a token and expiration save them, start grabbing the
        //friend list, and then navigate to the previous page
        if (!String.IsNullOrEmpty(accessToken) && (expirationDate != DateTime.MinValue))
        {
            ViewModel.AccessInfo = new AccessInfo() { ExpirationDate = expirationDate, Token = accessToken };
            ViewModel.SaveAccessToken();
            ViewModel.UpdateFriendList();
            ReturnToPreviousPage();
        }
    }, null);
}

Navigation is a little different on Windows Phone 7 and Windows 8. So I added a ReturnToPreviousPage() method in both the code-behind for the Metro and Windows Phone 7 versions of the application. Each of which contains the appropriate version of the navigation code.

void ReturnToPreviousPage()
{
   ViewModel.DispatchInvoke(() =>
   {
      (Window.Current.Content as Frame).GoBack();

   }
   );
}
 
void ReturnToPreviousPage()
{
   ViewModel.DispatchInvoke(() =>
   {
       NavigationService.GoBack();
   }
   );
}
Windows 8 Metro Version
 
Windows Phone Version

Retreiving the Friend List

The code for retrieving the friend list looks identical on both platforms. Facebook may not return the entire friend list in one call. If there are more friends to be retrieved in the return structure from the call there will be an address in a member in the return structure named Next (nested in Paging) which contains the address to the next page of the results. I'm not parsing the results myself but am instead making use of JSON.Net by James Newton-King. The results are parsed and accumulated into a temporary list. Once I know that I have all the results they are moved to the bindable list that drives the list box on the UI.

public void UpdateFriendList(string targetUrl = null, List previousUserList = null)
{
    if (AccessInfo == null)
        return;
    if (previousUserList == null)
        previousUserList = new List();

    var request = System.Net.HttpWebRequest.CreateHttp(targetUrl ?? String.Format(FRIEND_LIST_REQUEST, AccessInfo.Token));
    request.BeginGetResponse((o) =>
        {
            var response = request.EndGetResponse(o);
            var responseStreamReader = new StreamReader(response.GetResponseStream());
            string friendListText = responseStreamReader.ReadToEnd();
            Newtonsoft.Json.JsonSerializer s = new JsonSerializer();
            Data.FriendListResponse v = Newtonsoft.Json.JsonConvert.DeserializeObject(friendListText);
            if ((v != null) && (v.Data != null))
            {
                foreach (var user in v.Data)
                {
                    previousUserList.Add(user);
                }
            }
            if ((v!=null) && (v.Paging != null) && (v.Paging.Next != null))
                UpdateFriendList(v.Paging.Next, previousUserList);
            else
            {
                previousUserList.Sort((a1, a2) => { return a1.Name.CompareTo(a2.Name); });
                DispatchInvoke(() =>
                    {
                        FriendList.Clear();
                        foreach (var u in previousUserList)
                            FriendList.Add(u);
                    }
                );
            }

        }, null);
}

Dispatching Differences

There is a rule in Windows Platforms that you cannot modify the UI from a seconday thread. On the XAML based platforms you can ensure calls that modify the UI are marshalled to the UI thread by making use of an object called the Dispatcher. The way that you use this object differs on Windows Phone 7 and Windows 8. I abstracted away the differences by making a method called DispatchInvoke(). It compiles different on each platform and will call the appropriate code on each platform.

public void DispatchInvoke(Action a)
{
#if SILVERLIGHT
    if (MainViewModel.Dispatcher == null)
        a();
    else
        Dispatcher.BeginInvoke(a);
#else
    if ((Dispatcher != null) && (!Dispatcher.HasThreadAccess))
    {
        Dispatcher.InvokeAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, (obj, invokedArgs) => { a(); }, this, null);
    }
    else
        a();
#endif
}

Saving Data

For saving simple data types I tend to use a simple component that I made for Windows Phone 7 (it can be found here). On Windows 8 all file IO is asynchronous. So the component had to be modified to work on Metro. I've shown the details of the changes on another page. Since the Windows Phone 7 version uses a blocking call and the Metro version is asynchronous the calls could not be made to look the same. But this difference was compatmentalized to a single method.

public void SaveAccessToken()
{
   if (this.AccessInfo != null)
   {
#if NETFX_CORE
      DataSaver<AccessInfo>.SaveMyDataAsync(this.AccessInfo, "_accessToken.xml");
#endif
#if SILVERLIGHT
     DataSaver<AccessInfo>.SaveMyData(AccessInfo, "_accessToken.xml");
#endif
   }
}

Most of the code for this project is in the MainViewModel class. The entirity of the code for it is below. It shouldn't contain anything that you don't recognize from above. The using directives at the top contain conditional compilation directives since the namespaces in which some of the classes exists differs on Windows Phone 7 and on Windows 8 Metro.

using System;
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using Newtonsoft.Json;
using J2i.Net.FacebookAuthenticationTest.Data;
using J2i.Net.FacebookAuthenticationTest.Utility;


#if SILVERLIGHT
using System.Windows.Threading;
#endif

#if NETFX_CORE
using System.Threading.Tasks;
using J2i.Net.FacebookAuthenticationTest.Data;
using Windows.UI.Xaml;

#endif

namespace J2i.Net.FacebookAuthenticationTest.ViewModel
{
    public class MainViewModel: INotifyPropertyChanged 
    {
        const string FRIEND_LIST_REQUEST = "https://graph.facebook.com/me/friends?access_token={0}";


        public MainViewModel()
        {
#if SILVERLIGHT
            var a = DataSaver<AccessInfo>.LoadMyData("_accessToken.xml");
            if(a !=null)
            {
                this.AccessInfo = a;
                this.UpdateFriendList();
            }
#endif

#if NETFX_CORE
            DataSaver<AccessInfo>.LoadDataAsync("_accessToken.xml", (info, exc)=>
            {
                if (info != null)
                {
                    this.AccessInfo = info;
                    this.UpdateFriendList();
                }
            });
#endif
        }

        ObservableCollection<FacebookUser> _friendList;
        public ObservableCollection<FacebookUser> FriendList
        {
            get { return (_friendList) ?? (_friendList = new ObservableCollection<FacebookUser>()); }
            set { _friendList = value; }
        }
 

        string _friendListText = String.Empty;
        public string FriendListText
        {
            get { return _friendListText; }
            set 
            {
                if (value != _friendListText)
                {
                    _friendListText = value;
                    RaisePropertyChanged("FriendListText");
                }
            }
        }


        public void SaveAccessToken()
        {
            if (this.AccessInfo != null)
            {
#if NETFX_CORE
                DataSaver<AccessInfo>.SaveMyDataAsync(this.AccessInfo, "_accessToken.xml");
#endif
#if SILVERLIGHT
               DataSaver<AccessInfo>.SaveMyData(AccessInfo, "_accessToken.xml");
#endif
            }
        }

        AccessInfo _accessInfo;
        public AccessInfo AccessInfo
        {
            get { return (_accessInfo) ?? (_accessInfo = new AccessInfo()); }
            set 
            {
                if (_accessInfo != value)
                {
                    _accessInfo = value;

                }
            }
        }

        bool _authenticationAttempted = false;
        public bool AuthenticationAttempted
        {
            get { return _authenticationAttempted || (!String.IsNullOrEmpty(AccessInfo.Token)); }
            set { _authenticationAttempted = value; }
        }

#if NETFX_CORE
        static Windows.UI.Core.CoreDispatcher _dispatcher;
        public static Windows.UI.Core.CoreDispatcher Dispatcher
        {
            get
            {
                if (_dispatcher != null)
                    return _dispatcher;
                if ((Window.Current==null)||(Window.Current.Content == null))
                    return null;
                return Window.Current.Content.Dispatcher; 
            }
            set { _dispatcher = value; }
        }
#endif

#if SILVERLIGHT
        static Dispatcher _dispatcher;
        public static Dispatcher Dispatcher
        {
            get
            {
                if (_dispatcher!=null)
                    return _dispatcher;
                var app = (App.Current as J2i.Net.FacebookAuthenticationTest.App);
                if (app.RootFrame == null)
                    return null;
                return (app.RootFrame.Dispatcher);
            }
            set
            {
                _dispatcher = value;
            }
        }    
#endif


        public void UpdateFriendList(string targetUrl = null, List<FacebookUser> previousUserList = null)
        {
            if (previousUserList == null)
                previousUserList = new List<FacebookUser>();

            var request = System.Net.HttpWebRequest.CreateHttp(targetUrl ?? String.Format(FRIEND_LIST_REQUEST, AccessInfo.Token));
            request.BeginGetResponse((o) =>
                {
                    var response = request.EndGetResponse(o);
                    var responseStreamReader = new StreamReader(response.GetResponseStream());
                    string friendListText = responseStreamReader.ReadToEnd();
                    Newtonsoft.Json.JsonSerializer s = new JsonSerializer();
                  Data.FriendListResponse v = Newtonsoft.Json.JsonConvert.DeserializeObject<Data.FriendListResponse>(friendListText);
                  if ((v != null) && (v.Data != null))
                  {
                      foreach (var user in v.Data)
                      {
                          previousUserList.Add(user);
                      }
                  }
                  if ((v!=null) && (v.Paging != null) && (v.Paging.Next != null))
                      UpdateFriendList(v.Paging.Next, previousUserList);
                  else
                  {
                      previousUserList.Sort((a1, a2) => { return a1.Name.CompareTo(a2.Name); });
                      DispatchInvoke(() =>
                          {
                              FriendList.Clear();
                              foreach (var u in previousUserList)
                                  FriendList.Add(u);
                          }
                      );
                  }

                }, null);
        }


        void DispatchInvoke(Action a)
        {
#if SILVERLIGHT
            if (MainViewModel.Dispatcher == null)
                a();
            else
                Dispatcher.BeginInvoke(a);
#else
            if ((Dispatcher != null) && (!Dispatcher.HasThreadAccess))
            {
                Dispatcher.InvokeAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, (obj, invokedArgs) => { a(); }, this, null);
            }
            else
                a();
#endif
        }
        protected void RaisePropertyChanged(String propertyName)
        {
            if (PropertyChanged != null)
            {
                DispatchInvoke(()=>
                    {
                        RaisePropertyChanged(propertyName);
                    });
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}

Tags: , , ,

Apr 17 2012

Invoking through the Dispatcher on Windows Phone and Metro

Category: Desktop and Server | MobileJoel Ivory Johnson @ 09:26
Note: : Between the time that I wrote this and final release there were changes to the Windows Store Runtime. InvokeAsync nolonger exists. It has been replaced with RunAsync. Change noted below.

On the Windows Platforms there is a rule that you cannot modify UI elements from secondary threads. On Microsoft's XAML based platforms there is a member that exists on most UI objects called the Dispatcher that can be used to marshal a call to the proper thread.

On Windows Phone 7 and Windows 8 the way you go about calling this thread differs. I was recently working with some code that needed to compile for both platforms and wanted to minimize the amount of code that had to be wrapped in conditional compilation blocks. To do this I made a single method to handle my dispatching. The method itself contains conditional compilation blocks but because of this method I didn't need the blocks when I needed perform operations on the UI thread.

public void DispatchInvoke(Action a)
{
#if SILVERLIGHT
    if (Dispatcher == null)
        a();
    else
        Dispatcher.BeginInvoke(a);
#else
    if ((Dispatcher != null) && (!Dispatcher.HasThreadAccess))
    {
        Dispatcher.InvokeAsync( //RTM change
        Dispatcher.RunAsync(
                    Windows.UI.Core.CoreDispatcherPriority.Normal, 
                    (obj, invokedArgs) => { a(); }, 
                    this, 
                    null
         );
    }
    else
        a();
#endif
}

The code will compile for both Windows Phone 7 and Windows 8 Metro without any alterations. Using the code is the same regardless of which of the two platforms that you are using.

DispatchInvoke(()=>
  {
    //your operations go here
    TextBox1.Text="My Text";
  }
);

Tags: , , ,

Apr 3 2012

Getting Assembly Version Number in WinRT

Category: Desktop and Server | MobileJoel Ivory Johnson @ 09:19

It seems that every time one makes a shift from one .Net platform to another the method you use to reflect the version number for an assembly changes. I needed to get this information for a WinRT program earlier and was able to do so with a regular expression and the slightly different reflection methods in WinRT. The code follows:

 

var asmName = this.GetType().AssemblyQualifiedName;
var versionExpression = new System.Text.RegularExpressions.Regex("Version=(?<version>[0-9.]*)");
var m = versionExpression.Match(asmName);
string version = String.Empty;
if (m.Success)
{
    version = m.Groups["version"].Value;
}

Tags: ,

Mar 29 2012

External Motion Sensor for Windows 8

Category: Desktop and ServerJoel Ivory Johnson @ 15:12

I ordered the STEVAL-MKI119V1 eMotion sensor board for Windows 8 earlier this week and it showed up today. Unforunately it looks like I can't start using it just yet. To use the device it is necessary to update the firmware on the board. But the firmware isn't openly available on the website of the vendor. You've got to fill out a request form for it. If/when it is approved the software will be made available to you. 

 

If you plan on ordering on go ahead and fill out the form the same day that you purchase it so that you might have a chance of having the approval by the time the hardware arrives. You can request access to the software here: http://www.st.com/internet/evalboard/product/252756.jsp

The instructions on performing the update can be found here:

http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/USER_MANUAL/DM00041151.pdf

 

 

Tags:

Mar 24 2012

Windows 8 : Development Installation Options - USB (Windows to Go)

Category: Desktop and ServerJoel Ivory Johnson @ 07:20

The consumer preview of Windows 8 has been available for almost a month now. I've got the OS running as the main operating system on three of my computers; a slate, a tablet, and a desktop. While running natively on hardware is, in my opinion, the best way to run Windows 8, there are various reasons for which some one may want to do this such as not having access to additional hardware (or the desired configuration being to expensive for multiple machines).

 

I was looking at some of the other options for running Windows 8. These included the following:

 

  • Hardware Emulation
    • VMWare
    • Sun Virtual Box
    • VMWare
  • USB Installation
  • VHD Boot
Hardware Emulation is straight forward. I tried out Sun Virtual Box during the first release of Windows 8 CTP (at the time it was the only emulator that would work!). Since then VMWare has updated their products to have compatibility too. Though with VMWare there are a few things you'll want to do to ensure that you don't run into problems. When you are creating the new Virtual Machine select the option to install the operating system later. The automatic OS installation doesn't yet target Windows 8. Secondly you will want to edit the virtual machine configuration and remove the floppy disk. There's some other nebulous error that you will get during installation if the floppy disk is still present. I've found the performance to be acceptable within emulation (your mileage may varry since emulation performance is necessarily dependent on the performance of the host machine). But I find it more usable when it is running in full screen mode. It is difficult to hit the one pixel boundries on the edges of the screen in windowed mode. 

USB installation for the most part worked pretty well. But during operations that required heavy IO for the boot drive other task that required some level of IO appeared to freeze (which are more operations than you would think). To make a USB installation you will need to already have an up and running installation of Windows 8 (either in an emulator or on a real device). The instructions for the process can be found here.  If you look in the Windows Explorer you'll see that the main drive still shows as a removable drive. 

This causes an issue with installing the developer tools. The developer tools will *not* install on a removable drive. 

 

I tried to do a few things to circumvent this and finally found something that works. I had to make a VHD on my USB key and mount it and use that as the installation target.  I assigned this VHD drive the letter [P:] and tried the installation process again and it worked. 

 

 

VHD means Virtual Hard Disk. It's a file that contains an entire file system packaged in a file. Virtual PC uses this format but you can also make them at will from the disk manager. To make a VHD do the following. 

 

  1. Open the Control Panel
  2. Open  "Administrative Tools"
  3. Open "Computer Management"
  4. On the left pane select "Disk Management" under the "Storage" group
  5. Right-click on "Disk Management" and select "Create VHD"
    1. Select the maximum size of the virtual drive
    2. Select whether you want to preallocate the space or allocate it as needed
  6. Click on OK. The drive is automatically mounted 
  7. Right-click on disk name  and select "Initialize."
  8. Click on OK on the dialog that shows up
  9. Right-click on the area to the right of the disck and select "New Simple Volume."
  10. On the dialog that shows click on "Next" until you are able to select a drive letter. 
  11. Select a drive letter and click "Next"
  12. Enter a name for the volume and click "Next"
  13. Click "Finish."
After you click on "Finish" the drive will be available in the file explorer and available as an installation target. 

I'm still looking into the option of booting up from a VHD. With VHD bootup the operating system would b installed in a virual hard drive that is saved on the primary drive. When the computer is turned on you get the option of booting up into the main OS or into the VHD.  But it seems that my hard drive encryption software is causing some problems. I'll post back after I get the VHD option working. 


 

 

Tags:

Jan 29 2012

Sparse Array class for .Net

Category: Desktop and Server | MobileJoel Ivory Johnson @ 03:09

Download Code(312 Kb)

Introduction

I had the need for a dynamically growing sparsely populated array. "Sparse" implies that there will be a lot of elements that contain empty values between the ones that contain non-empty values. The .Net collections namespace doesn't contain anything that meets this need. The ArrayList class dynamically grows, but it would have elements allocated for the empty and non-empty values alike. I plan to use this code on devices that have limited memory so this wouldn't do. I ended up making my own class to satisfy this need. While my initial need for this code is for byte arrays I made the code generic so that it can be used with other data types.

How Big is this Class?

Since I will be talking about memory allocation I'll need to also talk about how to get a sense of how much memory that an instance of something costs. This won't account for 100% of the memory that is consumed by by allocation of the object. But it will be close enough for you to start making judgements about if one object cost more memory or less memory than another.

 

There are a number of predefined value types for which the size is well known. Here are some of the most common ones.

TypeSize (in bytes)
byte 1
int 4
short 2
float 2
double 4
char 2

If you build a struct it is a value type too. The size of a struct will be about the sum of the size of its members. Here is an example.

struct Location
{
    public int LocationID;   // 4 bytes
    public double Latitude;  // 4 bytes
    public double Longitude; // 4 bytes
    public double Elevation; // 4 bytes
}

The size of this structure is 16 bytes. Now what happens if you add a reference type (something that is defined as a class instead of a struct)? How big will it be? I'll add a string to the previous example.

struct Location
{
    public int LocationID;      // 4 bytes
    public string LocationName; // ?
    public double Latitude;     // 4 bytes
    public double Longitude;    // 4 bytes
    public double Elevation;    // 4 bytes
}

There are two elements of memory to consider for the reference field. There is the size of the reference and the size of the object to which it is pointing. Think of the LocationName field in the example above as holding a memory address to the area where the string is being held. The size of this memory address will depend on what type of processor architecture that the code is running against. If the code is JIT compiled for a 32-bit system then the refernece will be 32-bits (4 bytes) in size. If it is JIT compiled for a 64-bit system then the refenrece will by 64-bits (8 bytes) in size. When I am working with just a desktop then I do my calculations based on 64-bit systems. But the code on this article will run on Windows Phone so I will be taking both into consideration. There is also other elements within an objects header that is around 8 bytes. The other element of memory to take into the consideration is the size of the string itself. If the string has not yet been assigned and the element is null then the second element of size to consider will have a size of zero. If the string is assigned a value then the second element will be what ever memory is consumed by the string.

It is possible for multiple structs to refer to the same instance of a refernece type. When this occurs you'll want to make sure that you don't count the memory taken up by the instances of the reference type multiple times.

Now let's add an array and see what that does for our memory calculations. The array itself is a reference type. so the amount of memory the reference to it will consume is dependent on the processor architecture.

struct Location
{
    public int LocationID;         // 4 bytes
    public string LocationName;    // 4/8 bytes + string memory
    public double Latitude;        // 4 bytes
    public double Longitude;       // 4 bytes
    public double Elevation;       // 4 bytes
    public int[] SomeRandomArray;  // 4/8 bytes + array memory
}

The size of the memory associated with the array will be the sum of the size of the elements that it contains. If the array contains value types (the above contains a value type of int) then the memory allocated when the array is initialized is sizeof(int) (4 bytes) multiplied by the number of elements in the array. If the array contains reference types then the memory consumed by the array will be the size of the reference (4+8 bytes on a 32-bit system, 8+8 bytes on a 64-bit system) multiplied by the number of elements that the array can hold. This doesn't include the size of the individual instantiated instances of elements it contains.

What happens if I change any of the above from a struct to a class? Once a type is made into a reference type it is going to also have an object header. For a struct when you declare a variable all of the memory that is going to be used by the immediate members is going to be allocated. With a class only the memory for the reference (4 bytes on 32-bit, 8 bytes on 64-bit) is allocated. The memory needed for the members of an reference type is not allocated until there is a call to new. Also note that the memory for the instances of a reference type are allocated on the heap while for a value type they are allocated on the stack.

A Look Sparse and Contiguous Memory Allocation

If we take a look at how memory is allocated for a sparse array and a contiguous (normal) array the reason I needed this will be more clear. As an oversimplified example let's say that that an array of 40 elements must be allocated. Regular arrays will allocate the memory contiguously; the bytes associated with the array will be in the same block of memory. Lets say our sparse array is allocating blocks of memory for five elements at a time. Below the blocks that are in blue represent areas in which there is non-empty data.

Contiguous Array
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
Sparse Array
00 01 02 03 04
05 06 07 08 09
20 21 00 00 00
00 00 00 00 34
35 36 37 38 39

At a glance the sparse array is taking up less memory than the conventional array. There are still some empty elements within the structure. This is because it's allocating memory for a range of index. If there's even a single non-empty element within a 5 block range then there's an allocation for all 5 blocks. Whether or not this results in less memory being allocated overall is going to depend on the usage patterns for the sparse array. It will work best when the populated elements are clustered closely to each other.  Can we get rid of the empty elements all together? We could by reducing the size of the chunks allocated. The smaller the chunks the lower the opportunity for empty positions within chunks to exists. If memory was allocated for single elements (a chunk that only holds one element) then we would only have populated elements in the list. But is this better?

It may be. But to get a better answer to this question there's a cost that as of yet has remained invisible for the sparse array. There's a structure for holding  each chunk that looks like the following in my implementation.

public class ArrayChunk<T>
{
    public int StartIndex { get; set;  } //4 bytes needed to contain an integer value

    public int EndIndex
    {
        get
        {
            if (Data == null)
                return -1;
            return StartIndex +  Data.Length-1;
        }
    }
    public T[] Data { get; set;  }
}

In addition to the array that holds the elements of the chunk itself there is also a field to hold the start index for the array. The start index consumes 4 bytes of memory. So there is an overhead of no less than 4 bytes for each chunk allocated.  Consider a conventional and a sparse array both of which are fully populated with 100 bytes of data. Also assume that the sparse array allocates memory for 10 bytes at a time. The memory consumed by the conventional array will be about 100 bytes. The memory consumed by the sparse array will be around 140  bytes. If I reduced the size of the chunks to only having data for 2 bytes of memory then we end up needing at least 6 bytes for each chunk. For the fully populated 100 element collection this would translated to no less than 600 bytes. With results like that one may wonder why even bother with the sparse array.  But consider another scenario. Lets say that only 20 elements of the array are populated with 10 elements at the begining of the array and 10 at the end. For the conventional array the memory consumed will still be at least 100 bytes. For the sparse array it is around 28 bytes. Something that may become apparent is that the best case scenarios for this sparse array will occur when it partially populated and the populated data items are clustered close to each other.

Growing

The conventional array cannot grow. Once allocated its size is fixed. There are other collection classes within .Net that can grow such as the List<T> derived classes or the MemoryStream class. My understanding is that once the memory buffer for any of these classes is consumed it will allocated a new memory buffer of twice the size as the what it had, copy all of it's data to the new buffer, and then discard the old buffer to be reclaimed by garbage collection later. In trying to confirm this I found the source code for the MemoryStream class. The code of interest is below

 

            //From https://singularity.svn.codeplex.com/svn/base/Libraries/System.IO/MemoryStream.cs

            private bool EnsureCapacity(int value) {
            // Check for overflow
            if (value < 0)
                throw new IOException("IO.IO_StreamTooLong");
            if (value > _capacity) {
                int newCapacity = value;
                if (newCapacity < 256)
                    newCapacity = 256;
                if (newCapacity < _capacity * 2)
                    newCapacity = _capacity * 2;
                Capacity = newCapacity;
                return true;
            }
            return false;
        }

        // Gets and sets the capacity (number of bytes allocated) for this stream.
        // The capacity cannot be set to a value less than the current length
        // of the stream.
        //
        //| <include file='doc\MemoryStream.uex' path='docs/doc[@for="MemoryStream.Capacity"]/*' />
        public virtual int Capacity {
            get {
                if (!_isOpen) __Error.StreamIsClosed();
                return _capacity - _origin;
            }
            set {
                if (!_isOpen) __Error.StreamIsClosed();
                if (value != _capacity) {
                    if (!_expandable) __Error.MemoryStreamNotExpandable();
                    if (value < _length) throw new ArgumentOutOfRangeException("value", "ArgumentOutOfRange_SmallCapacity");
                    if (value > 0) {
                        byte[] newBuffer = new byte[value];
                        if (_length > 0) Buffer.BlockCopy(_buffer, 0, newBuffer, 0, _length);
                        _buffer = newBuffer;
                    }
                    else {
                        _buffer = null;
                    }
                    _capacity = value;
                }
            }
        }

This behaviour is just fine for typical scenarios, but I will be working with what are relatively large buffers (in comparison to the memory available on the devices on which I will be running my code). So I'd prefer to keep the ceiling for the maximum amount of memory allocation that occurs within the programs that I have in mind. It's also worth mentioning that the .Net runtime treats "large" objects differently than it does small ones. For more information take a look at The Dangers of the Large Object Heap. Large objects (around 85,000 bytes or larger) or allocated on a separate heap than small objects (under 85,000 bytes). During garbage collection the .Net garbage collector will try to condense the objects in the smaller heaps to being in contiguous memory. Objects in the LOH (Large Object Heap) are not as easily addressed. From the referenced article:

Large objects pose a special problem for the runtime: they can’t be reliably moved by copying as they would require twice as much memory for garbage collection. Additionally, moving multi-megabyte objects around would cause the garbage collector to take an unreasonably long time to complete.


.NET solves these problems by simply never moving large objects around. After large objects are removed by the garbage collector, they leave behind holes in the large object heap, thereby causing the free space to become fragmented. When there’s no space at the end of the large object heap for an allocation, .NET searches these holes for a space, and expands the heap if none of the holes are large enough. This can become a problem. As a program allocates and releases blocks from the large object heap, the free blocks between the longer-lived blocks can become smaller. Over time, even a program that does not leak memory, and which never requires more than a fixed amount of memory to perform an operation, can fail with an OutOfMemoryException at the point that the largest free block shrinks to a point where it is too small for the program to use.

There are improvements in the LOH in .Net 4.5. Also note that on devices with more constrained memory (such as Windows Phone) there is no LOH. But there are still advantages to avoiding fragmented memory conditions.

Collection of Chunks

While the code I've written is mean to be a type of collection class the code is still dependent on a collection class for holding onto the chunks that it has. It is possible to use one of the List<T> classes for this or a Dictionary<T1,T2> for this. I've decided to go with the List<T>. Now doesn't it look dubious that I talked about the memory usage patterns of the List<T> class and now I'm using it in my underlying implementation! Isn't that just going to cause the same problem that I described above with memory fragmentation? Well, no, at least not as severe. The List<T> contains references to ArrayChunk instances. So these will either be 4 bytes or 8 bytes. Let's assume the worst case which is 8 bytes. To grace the large object boundaries the array list would need to grow to more than 10,000 elements ( (85,000 / 8)=num of items needed to make the ArrayList large. 85,000 is the large object size and 8 is the amount of bytes needed to store a reference). The number of elements needed to make the array list this size is going to depend on how many elements you allow to be stored in each ArrayChunk. When the array does become large enough to occupy the LOH area the scenario is still better than what would happen with a conventional array since the block of memory occupying the LOH is smaller than the block of memory that would have been occupied by a contiguous array of the elements.

For what the sparse array is capable of doing in the code presented with this writeup the LinkedList<T> would have been suitable (actually more suitable). The List<T> that I use is primarily stepping forward and backwards in the list (I wrote the code making the assumption that read and writes to the list will tend to be clustered close to each other). I used the List<T> because it seems to be a better fit for some modifications I plan to do to this code in the future. I won't detail the details of those plans now since they could change. Consequently of those plans do change then I may swap out the List<T> with the LinkedList<T>. When I do make changes I want to ensure that I don't break any of the existing behaviour of the class. The project for this code also contains a few unit test to validate that the behaviour of the ArrayList<T> doesn't vary from expectations.

Testing

There's a small test project included with the code. It will become more important as time goes on because as I make additions to this code I want to ensure that I don't break any of the behaviours that are already present. Right now the test are just checking against the virtual size of the array, ensuring the memory chunks are allocated or deallocated as expected, and that data is preserved.

What is EmptyValue For?

In the sparse array cells that have not been written to are to be treated as though they exists and they contain some default value. That default value is stored in EmptyValue. There are multiple uses for this member. If there is an attempted read from an unallocated cell EmptyValue is returned. When the sparse array is searching for chunks to deallocate it will check the contents of that chunk to see if all of its elements are equal to EmptyValue. When a new SparseArray is instantiated the EmptyValue field is initialized by calling the default constructor/initializer for the type that it hosts. For the numeric types this will end up being a zero value. If this isn't appropriate for the data type that you are using there is a delegate named IsEmptyValue to which you can assign a method that returns true to indicate that a value or instance should be considered empty and false otherwise.

Using the Code

Use of this code is not much unlike how you might use a strongly typed fixed size array. The main difference is the upper bound on the SparseArray<T> grows as needed to accomodate writes to positions within the least. Reading from locations beyond the upper bound will not result in an exception. If some one reads from an indix that is above the size of the array it remains unchanged. But if someone writes to a location above the upper limit then the array will update its reported size and allocate an ArrayChunk if needed.

Class Interface

Properties
Name Access Description
ChunkSize int Indicates the number of elements that each ArrayChunk can hold
Length int Returns the virtual size of the sparse array
ChunkCount int Returns the total number of chunks that the sparse array has.
this[int index] (Generic) Indexer for accessing contents of array
Methods
Name Description
Condense Searches through the sparse array and removes the chunks that contain only empty values
ctor() default constructor. Will create a sparse array with a chunk size of 256 elements
ctor(int size) Creates a sparse array with a chunk size that is determined by the size parameter passed.
ctor(int size, int chunkCount) Creates a sparse array with a chunk size that is determined by the size parameter passed. The chunkCount may be used as a hint for preallocating some memory.

Usage Example

 //Initialize an instance of the array
SparseArray<int> myArray = new SparseArray<int>();

//Populate the array with a few elements
myArray[15] = 23;
myArray[1024] = 2;

//Print the size of the array. Will be 1025 (remember this is a zero based array)
Console.Out.WriteLine("Virtual size of the array: {0}", myArray.Length);

//Read from a position beyond the limit
Console.Out.WriteLine("Value in position 2048 : {0}", myArray[2048]);

//Print the size of the array. Will be 1025 (remember this is a zero based array)
Console.Out.WriteLine("Virtual size of the array: {0}", myArray.Length);

//Show how many chunks the sparse array has. 
Console.Out.WriteLine("Chunk count: {0}", myArray.ChunkCount);

//Set the only populated element in the second chunk to zero and then condense the array
myArray[1024] = 0;
myArray.Condense();

//Check the chunk size again. It should be reduced. 
Console.Out.WriteLine("Chunk count: {0}", myArray.ChunkCount);

Tags:

Oct 11 2011

What Does Windows 8 Mean for Windows Phone Developers?

Category: Desktop and Server | MobileJoel Ivory Johnson @ 01:24

It was only a few weeks ago that Windows 8 was unveiled at the Build conference. At first glance it looks a lot like Windows Phone with heavy use of the Metro visual language. The only part of the system that hasn't had the Metro touch is the desktop (unlike previous versions of Windows the Desktop is not something that is always running). The Start menu looks like the Windows Phone start screen only it scrolls horizontally instead of vertically. The only mention of Silverlight is that you could still use it in Desktop mode for backwards compatibility, but the Metro [default] instance of IE would run no plug-ins, including Silverlight. The programming model also is not based off of Silverlight or the Desktop .Net runtime. Its based on something new called WinRT (Windows Runtime). 

At first glance this is something that has concerned Silverlight and Windows Phone developers. At first glance some one might come to the conclusion that the skill in which he or she has invested has become second class in Windows 8. Is Silverlight really getting killed off? What's going to happen for the Silverlight based Windows Phone?

I don't know the future any more than the next person, but what I saw at Build isn't something that raised concern. I found it to be rather reassuring. Before I explain why let me grant the elephant in the room, the rumor that Silverlight is going to be dead. I don't believe this rumour. For years people have predicted that certain Microsoft Technologies were dead (DirectX, .Net, and many other technologies that we still use today). But I'll grant it anyway so that we can explore what seems to be a popular concern. 

Let's assume that next year Microsoft announces that it is going to sunset Silverlight and toss out the Windows Phone programming model in favour of the Windows 8 programming model. What does this mean for the skills that you have developed? Are they now useless? You've been developing skills in C#/VB, XAML, asynchronous programming, and some APIs that were specific to Silverlight and Windows Phone. Let's look at how each one of these will contribute to your Windows 8 development. 

Languages: C# and VB

C# and VB are still being used on Windows 8. If you've been using these languages you can continue to use them. Additionally if you know C++ or have algorithms that had been written in C++ you'll be able to port them over to Windows 8. Windows 8 also supports JavaScript as a programming language too. 

XAML

XAML is still used on Windows 8 for building your UI. Many of the elements you've become familiar with are present in addition to some new ones. No huge changes there. 

Asynchronous Programming

One of the challenges for developers that were new to Silverlight was that task that one may have been used to doing synchronously are only available as asynchronous calls. On Windows 8 you'll find that many of the tasks that were asynchronous in Silverlight and Windows Phone are still asynchronous. Additionally other APIs have been made asynchronous, including File IO. 

The Familiar and What This All Means

You'll come across APIs that look similar of not identical to what you've seen in Windows Phone and Silverlight. Windows 8 has the concept of an application getting tombstoned, specifying the permissions it needs, and so on. Windows 8 Metro applications will only be distributed through the Marketplace. Doesn't all of this sound familiar. If you are a Windows Phone developer it should. You've already got a head start on Windows 8 development. This is far from the doom and gloom picture that some stories would have some one believe. 

If you want to dive into Windows 8 programming the 64-bit development images are available for download. I suggest running them on real hardware. I tried them in the emulator VirtualBox and it's just not the same experience there. 

Tags: , , ,

Jul 10 2011

XNA Animated Sprite code uploaded to CodeProject.com

Category: Desktop and ServerJoel Ivory Johnson @ 06:51

I've uploaded some code I was working on to animate sprites in XNA.

Animating a sprite isn't difficult, but I wanted some way to animate them but reduce the coupling between code and the animation. The Content Pipeline is perfect for this. So I created a component that will handle the animation scenarios that I need along with a content extension so that I could load these animations as content. Right now the animation information is in an XML file. This is a stepping point towards having a graphical tool for handling this.

You can read about the code here or see a brief description of it in the video below

Tags: , , ,

Feb 10 2011

Double Precision Vector3

Category: Desktop and Server | MobileJoel Ivory Johnson @ 03:29

Download the code (2.90 KB)

 

I was working on an educational project using Windows Phone and XNA on the desktop (the phone will be controlling the desktop). The project involves demonstrating the laws of celestial mechanics. So the modeled entities have attributes with large values (ex: the mass of a planet in kilograms, the distance the planet is from its sun in meters, so on). In the Xna portion of the program the Vector3 class appeared to be a good fit for modeling a planet's position, velocity, acceleration, and so on. My only concern with Vector3 is the precision of the numeric type that it uses. It uses a single precision number. When I started my initial test I was seeing how small objects reacted on the earth's surface just to make sure that my gravity calculations were correct. Everything worked fine; the object would fall toward the earth with the expected acceleration. So I went straight from modeling a small object on the earth's surface to modeling the Earth's moon. That's when things broke down. The numbers coming back from the gravity calculations were all wrong. 

It turns out I was running into a precision problem. Floating point types have enough precision to hold the final results of my calculations, but not enough prevision to hold the large intermediate values during the calculations. There are three ways to solve this:

  1. Use a Vector class with a higher precision numeric type
  2. Copy values from Vector3 to doubles, perform calculations, copy results back to Vector3
  3. Perform my calculations using Astronomical Units (AU) instead of meters. 
I started with trying to copy values to double types before doing calculations first. That works, but I had concerns with the code getting messy and the overhead in coding that way. I thought about using astronomical units. But that would add an extra mental layer of complication. I think of calculations for gravity in terms of meters and trying to work in some other unit would likely lead to problems. There was no higher precision Vector3 class available. So last night I converted the Vector3 class to a double-precision version of itself that I named Vector3D.  A majority of the methods available on Vector3 are available on the Vector3D class. 
I replaced the Vector3 with the Vector3D class and everything worked as expected. 

I figure at some point some one else will run into this problem so I've posted a copy of this class (link at the top of this entry). If I need to add more functionality to this class I'll be updating the version at the above link to. 

Tags: ,

Dec 15 2010

Calculating Distance from GPS Coordinates

I've been carrying this equation around forever and a day and thought I would share it. With this equation you can calculate the distance between GPS coordinates. I tend to use SI units, but you should be able to easily adjust it for units of your choosing.

using System; 
using System.Device.Location; 
 
namespace J2i.Net.GPS 
    public static class DistanceCalculator 
    { 
 
        public const double EarthRadiusInMiles = 3956.0; 
        public const double EarthRadiusInKilometers = 6367.0; 
        public const double EarthRadiusInMeters = EarthRadiusInKilometers*1000; 
 
        public static double ToRadian(double val) { return val * (Math.PI / 180); } 
        public static double ToDegree(double val) { return val * 180 / Math.PI; } 
        public static double DiffRadian(double val1, double val2) { return ToRadian(val2) - ToRadian(val1); } 
 
 
 
        public static double CalcDistance(GeoCoordinate p1, GeoCoordinate p2) 
        { 
            return CalcDistance(p1.Latitude, p1.Longitude, p2.Latitude, p2.Longitude, EarthRadiusInKilometers); 
        } 
 
        public static Double Bearing(GeoCoordinate p1, GeoCoordinate p2) 
        { 
            return Bearing(p1.Latitude, p1.Longitude, p2.Latitude, p2.Longitude); 
        } 
 
        public static double CalcDistance(double lat1, double lng1, double lat2, double lng2, double radius) 
        { 
 
            return radius * 2 * Math.Asin(Math.Min(1, Math.Sqrt((Math.Pow(Math.Sin((DiffRadian(lat1, lat2)) / 2.0), 2.0) 
                + Math.Cos(ToRadian(lat1)) * Math.Cos(ToRadian(lat2)) * Math.Pow(Math.Sin((DiffRadian(lng1, lng2)) / 2.0), 2.0))))); 
        } 
 
        public static Double Bearing(double lat1, double lng1, double lat2, double lng2) 
        { 
 
            { 
                var dLat = lat2 - lat2; 
                var dLon = lng2 - lng1; 
                var dPhi = Math.Log(Math.Tan(lat2 / 2 + Math.PI / 4) / Math.Tan(lat1 / 2 + Math.PI / 4)); 
                var q = (Math.Abs(dLat) > 0) ? dLat / dPhi : Math.Cos(lat1); 
 
                if (Math.Abs(dLon) > Math.PI) 
                { 
                    dLon = dLon > 0 ? -(2 * Math.PI - dLon) : (2 * Math.PI + dLon); 
                } 
                //var d = Math.Sqrt(dLat * dLat + q * q * dLon * dLon) * R; 
                var brng = ToDegree(Math.Atan2(dLon, dPhi)); 
                return brng; 
            } 
        } 
 
    } 
 

Tags: ,

Oct 5 2010

IE9 Rocks!

Category: Desktop and ServerJoel Ivory Johnson @ 06:56

And now for some off topic comments!

I've been using IE9 Beta since it was released to public beta and I have to say it rocks! I've installed it on most of my machines and have to say that it looks clean and runs fast. The interface has as many buttons as needed and no more. And the things you can do with HTML 5 are awesome!

Tags:

May 30 2010

Visual Studio Snippets

Category: Desktop and Server | MobileJoel Ivory Johnson @ 03:11

As a developer if you are not using some type of code generation tools then you are not achieving your true potential. In addition to plugins being available such as ReSharper or CodeRush Visual Studio has had the ability to automate some code generation builtin. One of the facility provided is code snippts. A snippet is a code template. You can define your own for patterns that you find yourself implementing over and over.

If you've never used snippets and want to get started then start off by downloading this file. It's a template for making your own snippets.  Then watch this video demonstrating how to use that file to create and use your own snippets.

 

Tags: ,

May 27 2010

Forward Comaptibility Update for Visual Studio 2010

Category: Desktop and ServerJoel Ivory Johnson @ 02:32

Now that Visual Studio has gone RTM you may find yourself needing to use both Visual Studio 2008 for maintaining your existing Windows Mobile projects while using Visual Studio 2010 for other things. You may have also noted that Visual Studio 2008 does work with TFS 2010. To resolve this problem there's a forward compatibility update for Visual Studio 2008. The update weighs in at 11 megabytes and will allow Visual Studio 2008 to work with TFS 2010.

You can download it from here.

Tags:

May 21 2010

What is the Cloud?

Category: Desktop and ServerJoel Ivory Johnson @ 07:13

The other day I was asked "What is cloud computing." I looked at it as being a concept that you just know like "time." How many of you can give a complete definition of time without referencing a dictionary? A short version of what I told him is that if some one uses cloud services it means they use computers that are some where else owned by some one else.

Cloud

But I heard some one give a nice analogy explaining cloud computing. So I am taking it as my own.

I live in a house. Imagine for a moment that I decided to power the house by means of my own. I'd have to have a generator of some type constructed (solar batteries, hydroelectric generator, windmill, nuclear, what ever). That generator would require some type of maintenance. If I needed more power than the generator could produced then I would either need to suffer through having sufficient power or I would need to add more generators. If I add more generators and then find that many times I don't need them then I have the extra expense of maintaining these extra generators. I don't know anything about maintaining such equipment myself. So I'd either have to be trained in doing so in addition to the other tasks I do around the house or would need to pay some one else to take care of this.

Thankfully that's not how things work at my house. My neighbors and I get our electricity from our power company. I have no idea where it is generated or how it is generated. I honestly don't care as long as it makes it's way to me. If I need to use more electricity than usual in a month it's available. If I use less than I can do so and pay less. I don't have to worry about the space constraints for a generator or hiring staff to take care of it. I just pay for the electricity I need and go on about my business.

That's pretty much how Cloud Computing works in a nutshell. Only instead of purchasing electricity you are purchasing computing and/or storage. You may not know where the computer is actually located. On some plans if more computational power is needed the number of machines allocated can automatically increase for as long as needed and then decrease when no longer needed. There's no need to worry about maintaining the machines as the company that sold them will take care of that.

Tags: ,

May 3 2010

Try Windows Azure and SQL Azure Free for One Week

Category: Desktop and ServerJoel Ivory Johnson @ 14:24

Now is a perfect opportunity to get your feet wet with Microsoft Cloud Computing. You can try SQL Server Azue and Windows Azure free for one week. You can get a Windows Azure bootcamp pass to learn Azure at your own pace between May 3 and May 10. You can find information on the bootcam pass and the learning material  here.

Tags: