HTML5 Mandelbrot Fractals

As a fun little project, I created a little HTML5 app that generates fractals from the Mandelbrot Set.  It’s based on a similar C++ program written by “jonoerik”, which you can find here.

Be aware that you can lock up your browser if you play with the Advanced Settings too much!

ASP.NET 4.5, C# and Visual Studio 2012 Expert Skills – Video course now available

The video course for the ASP.NET 4.5, C# and Visual Studio 2012 Expert Skills course is now available from aspnetcentral.com.

New HTML5 version of Life

To get to grips with HTML5, I decided to create an HTML5 version of my Life cellular automata program. You can now run Life inside your web browser, now with more buttons than ever before!

I recommend using Google Chrome to run HTML5 Life, as it is compatible with some of the new HTML5 user interface features.

ASP.NET 4.5, C# and Visual Studio 2012 Essential Skills – Video course now available

The video course for the ASP.NET 4.5, C# and Visual Studio 2012 Essential Skills course is now available from aspnetcentral.com.

Single Sign-On (SSO) from ASP.NET to PHP

I recently implemented the new ExcelCentral forums, and was faced with the challenge of integrating the login from our main ASP.NET site with the PHP-based Invision forum software.

To make this possible, I modified the forum software to retrieve ASP.NET’s login cookie and send a request back to the ASP.NET site to validate it and return the details of the logged-in user.

On the PHP side, the code to check whether a user is logged into the main site looks something like:

/* Get the ASP.NET Login cookie (ASPXAUTH) */
$sessioncookie = $_COOKIE['_ASPXAUTH'];

if ( !$sessioncookie )
{
    /* If we have no cookie, user is not logged in */
    /* Code for anonymous users here */
}
else
{
    /* Send the key from the ASPXAUTH cookie to a page within the ASP.NET application that will return the user's details */
    $userdata = file_get_contents('http://www.yourdomain.com/getloggedinuser.aspx?key='.$sessioncookie);

    if ($userdata == "")
    {
        /* The ASP.NET site did not consider the login cookie to be valid (possibly the session has expired) */
        /* Code for anonymous users here */
    }
    else
    {
        /* Parse the data that was returned from the ASP.NET system */
        $parseduserdata = json_decode($data, true);
        $userid = $parseduserdata['id'];
        $username = $parseduserdata['username'];
        /* Code for logged-in users here */
    }
}

Now we need to write the code for the getloggedinuser.aspx page within the ASP.NET system:

protected void Page_Load(object sender, EventArgs e)
{
    try
    {
        if (Request.QueryString["key"] != null)
        {
            // Retrieve the login key value from the querystring (this is the code from the ASPXAUTH cookie)
            string AuthKey = Request.QueryString["key"];

            // Decrypt the key and get the associated Forms Authentication ticket
            FormsAuthenticationTicket Ticket = FormsAuthentication.Decrypt(AuthKey);

            // Retrieve the user's details from the ticket
            string UserName = Ticket.Name;
            MembershipUser LoggedInUser = Membership.GetUser(UserName);
            string UserID = LoggedInUser.ProviderUserKey.ToString();

            // Output the user details in JSON format
            Response.ContentType = "application/json";
            Response.Write("{\"id\": \"" + UserID + "\",\"username\": \"" + UserName + "\"}");
            Response.Flush();
            Response.SuppressContent = true;
            HttpContext.Current.ApplicationInstance.CompleteRequest();
        }
        else
        {
            // Return a blank page if there is no key provided
            Response.Write("");
            Response.Flush();
            Response.SuppressContent = true;
            HttpContext.Current.ApplicationInstance.CompleteRequest();
        }
    }
    catch(Exception Ex)
    {
        // Return a blank page if an exception occurs
        Response.Write("");
        Response.Flush();
        Response.SuppressContent = true;
        HttpContext.Current.ApplicationInstance.CompleteRequest();
    }
}

By using FormsAuthentication.Decrypt as shown above, we can easily get the user details as long as we can provide the value of the user’s ASPXAUTH cookie. Remember that cookies are only shared across a single domain, so you won’t be able to implement single-sign-on across domains.

In my system, the login cookie is available on both excelcentral.com and on forums.excelcentral.com, so login can be shared between the two.  However, my aspnetcentral.com site wouldn’t be able to get the login cookie from excelcentral.com.

ASP.NET’s default behaviour can cause problems here, because it doesn’t mark cookies with a domain by default.  To change this, you need to edit Web.config with the following (within the system.web tag):

<httpCookies domain="yourdomain.com" />

This setting will mark ASP.NET’s login cookies with your domain, allowing them to be retrieved by any subdomains (eg forums.yourdomain.com).

ASP.NET 4.5 and Visual Studio 2012 Essential Skills book available

My new book for ASP.NET 4.5 and Visual Studio 2012 is now available from Amazon and other book retailers.

I’m currently working on the video version of the course, and hope to be able to offer it soon.

You can buy the new book from Amazon by clicking here.

ASP.NET multi-threading: Thread vs ThreadPool vs Task vs Parallel. Which one is the best choice?

I’m currently working on my upcoming ASP.NET 4.5 Expert Skills book, and it struck me that there are now at least 4 different options available to the programmer when implementing multi-threading. If you’re not already familiar with these classes, choosing between them is likely to be extremely difficult.

Let’s take some simple pseudo-code as an example:

foreach (var FileToEncrypt in FilesToEncrypt)
{
    EncryptFile(FileToEncrypt);
}

In this example, let’s imagine that the EncryptFile method is very processor-intensive, so we’d like to split the calls to EncryptFile into separate threads.

Using the Thread class

The Thread class has been around since the original release of the .NET framework, so  it’s likely that existing multi-threading code will use this class.

The Thread class is found in the System.Threading namespace.

Here’s how the multi-threaded code would look using the Thread class:

List<Thread> MyThreads = new List<Thread>();
foreach (var FileToEncrypt in FilesToEncrypt)
{
    Thread NewThread = new Thread(new ParameterizedThreadStart(FileToEncrypt));
    NewThread.Start(FileToEncrypt);
}

This looks fine as long as it is all that your program needs to do. But let’s assume that we need to do something with the encrypted files after the threads have finished encrypting them. We’ll need to add some code that waits until all of the threads have finished before continuing:

List<Thread> Threads = new List<Thread>();
foreach (string FileToEncrypt in FilesToEncrypt)
{
    Thread NewThread = new Thread(new ParameterizedThreadStart(FileToEncrypt));
    Threads.Add(NewThread);
    NewThread.Start();
    Stuff(FileToEncrypt);
}
bool AllThreadsFinished = false;
while (!AllThreadsFinished)
{
    AllThreadsFinished = true;
    foreach (Thread MyThread in Threads)
    {
        if (MyThread.IsAlive) AllThreadsFinished = false;
    }
    Thread.Sleep(1000);
}

We’ve had to add quite a lot of code to achieve it, but this code will now wait for all of the threads to finish. This isn’t the only way to achieve this using the Thread class, but it’s the easiest to understand and uses the least code.

The Thread class does a good job of splitting code into multiple threads, and will even benefit from the improvements to threading that were added to ASP.NET 4.5. If your existing code uses the Thread class, there’s really no need to change it.

Using the ThreadPool class

The ThreadPool class is another class that has been around since the first version of the .NET framework. ThreadPool offers more control over how threads are distributed to the computers processor or processors, but it is much harder to implement the ‘wait’ code that we used for the Thread class.

The ThreadPool class is found in the System.Threading namespace.

Here’s how our threading code would look using the ThreadPool class:

foreach (string FileToEncrypt in FilesToEncrypt)
{
    ThreadPool.QueueUserWorkItem(new WaitCallback(EncryptFile), FileToEncrypt);
}

This looks much easier, but the ThreadPool class doesn’t give us any way to check on the status of the thread that we just created, so how can we tell when it has finished?

There are some very complicated ways of extracting the status of the thread, but an alternative option is to maintain a counter that is incremented when the EncryptFile method finishes. We’ll call it: NumberOfFilesEncrypted

We can then wait for all of the threads to finish by using the following code:

foreach (string FileToEncrypt in FilesToEncrypt)
{
    ThreadPool.QueueUserWorkItem(new WaitCallback(EncryptFile), FileToEncrypt);
}
while (NumberOfFilesEncrypted < FilesToEncrypt.Count)
{
    Thread.Sleep(1000);
}

Of course, this is far from ideal. If one of the threads failed for some reason, the code would wait forever for the last thread to finish. This could be worked around with error handling and timeouts, but it’s really better to avoid the ThreadPool class if possible.

Using the new Task class

The Task class was introduced in .NET 4.0, but has only really been finalized in the .NET 4.5 release. The Task class combines the functionality of the Thread and ThreadPool classes to make threading easier and more efficient.

The Task class is found in the new System.Threading.Tasks namespace.

Here’s how our code would look using the Task class:

foreach (string FileToEncrypt in FilesToEncrypt)
{
    Task.Factory.StartNew(Argument => EncryptFile(Argument), FileToEncrypt);
}

Once again, of course, we need to check whether all of the threads have finished before continuing. We can do this in a very similar way to the Thread class, but with much less code:

List<Task> MyTasks = new List<Task>();
foreach (string FileToEncrypt in FilesToEncrypt)
{
    MyTasks.Add(Task.Factory.StartNew(Argument => EncryptFile(Argument), FileToEncrypt));
}
Task.WaitAll(MyTasks.ToArray());

The Task.WaitAll method makes everything much easier! If you have the choice between the Thread and Task classes, I’d recommend the Task class every time.

However, I’ve saved the best for last. The Parallel class enables us to carry out the task with even less code.

Using the new Parallel class

The Parallel class enables you to change any for or foreach loop into multi-threaded code. Every iteration of the loop will be intelligently assigned to a separate thread and will be executed in the most efficient way possible.

The Parallel class can be found in the System.Threading.Tasks namespace.

Here’s how our code would look using the Parallel class:

Parallel.ForEach(FilesToEncrypt, FileToEncrypt =>
{
    EncryptFile(FileToEncrypt);
});

You might be wondering how we wait for all of the threads to finish. In fact, the Parallel class handles this automatically! The foreach loop won’t finish until all of the threads have finished running.

If the code that you want to be multi-threaded can be expressed as a for or foreach loop, there’s little doubt that you want to use the Parallel class.

If you’re using ASP.NET 4.5, I would highly recommend using the Task class and Parallel classes and ignoring the older Thread and ThreadPool classes.

New Website Live

The ASP.NET 4.0 and Visual Studio 2010 course has moved to: http://www.aspnetcentral.com

The new site allows every lesson to be viewed as both a video and a PDF file.

ASP.NET Authentication Problems on Safari and the Google Nexus

Working on a new version of the learnasp4.com website, I stumbled across an issue with ASP.NET Authentication when streaming video to Google Nexus devices and the Safari Browser.

The new website uses an HTTP Handler to check whether the user is logged in and only serve video files to them if they are.  (HTTP Handlers are covered in Session 7 of the Expert Skills course).

On Internet Explorer, FireFox, Chrome and almost everything else, this worked fine.  When the browser sendt a request for the video file, it sends all of the ASP.NET session information along with the request and my handler was able to detect whether they were logged in.

However, on the Google Nexus, this doesn’t happen!  Instead of sending a request from the Chrome browser, the Google Nexus sends a request from its own media player, known as “Stagefright”.  The request from Stagefright is completely divorced from the browser session, so the handler does not see it as a logged-in browser.  Naturally, this means that the handler never sends any video to the Google Nexus!

On most devices, this is easily fixed by simply installing Flash.  Flash correctly maintains session information when requesting video, so this would be an ideal solution…except Google don’t support Flash on the Nexus.

The plot thickens still further when it becomes clear that Google have known about this issue since November 2008, but it’s interesting to note that the Safari browser has a very similar problem.

When Safari requests a video file, it sends the request through QuickTime.  Just like Stagefright, QuickTime sends the request without any session information, preventing the files from being secured using ASP.NET authentication.

This issue seems to be fixed in the latest versions of Safari, so perhaps there is still hope that Stagefright will eventually respect sessions as well.

There are many possible workarounds for this problem (such as providing a querystring parameter to the handler), but since it only seems to affect Google Nexus devices it doesn’t seem unreasonable to call on Google to fix what looks like a serious bug in their browser!

Expert Skills video course now available

The Expert Skills video course is now finished and available here.

You can watch some sample videos, and the entire Essential Skills video course absolutely free here.  There are now over 140 free video lessons – over 14 hours of free tutorials.