|Written by Ian Elliot|
|Wednesday, 29 August 2012|
Page 1 of 3
If you want to keep the user interface fast and responsive you have to follow the framework and create asynchronous functions - but how? This sounds complicated. The solution is to make use of Web Workers and wrap what you create so that it returns a promise. Let's see how it all fits together.
If you have missed any of the earlier ones they are:
A Slow Calculation
First let's start off with an example of a long computational task just asking to be implemented on a separated thread. For the sake of simplicity the calculation is to sum a large number of integers and return the total.
Of course in practice your task could be doing all sorts of interesting things that take a long time. You may also have to adjust the size of the for loop to take account of how fast your machine is.
To see this in action before you have moved it off to another thread add a button with id Button1 and perhaps a second button that does nothing that you can attempt to click to prove that the UI is frozen.
Now we can call the slow function when the button is clicked and to show that it has completed its work we can set the button's text to the result:
If you run this you will discover that when you click the button nothing works until the answer comes back from the function and is displayed on the button. If it all happens too quickly or slowly then change the number of loops.
Clearly this freezing of the UI is not good and this is the reason we need to use a separate thread for the calculation - or any task that takes similar amounts of time. That is we need a Web Worker.
Basic Web Worker
The good news is that Web Worker is very easy to use. What is slightly difficult is working out what you are not allowed to do and achieving simple communication between the threads. Ideally you should wrap any Web Worker tasks you create as promises so as to fit in with the rest of WinJS and to make your own code easier to use. But first let's take a look at how you make use of the worker object to implement another thread and then see how to package it as a function that returns a promise.
the code stored in myScript.js is running on a thread that is different from the UI thread and you have a Worker object created on the UI thread that allows you to interact with it.
First some basic rules.
The new thread cannot access any objects that the UI Thread can. This means it cannot interact with any global objects and it cannot interact with the DOM or the user interface in any way.
This may seem a little restrictive but it is a restriction that is necessary to make sure that the two threads you now have don't try to access the same object at the same time. If this was allowed to happen you would need to introduce a lot of complicated machinery - locks, semaphores and so on - to make sure that the access was orderly and didn't give rise to any very difficult to find bugs - race conditions, deadlock and so on.
in other words the Web Worker has big restrictions so that you can use it without complication and without any danger.
For most purposes it is sufficient and hence very effective.
To make up for this restriction there are two new objects that the Web Worker can access - WorkerNavigator and WorkerLocation. The navigator provides basic information about the app's context - the browser in use, appName, appVersion and so on. The location object provides details of where the app is in terms of the current URL
if these two objects don't provide enough information you can easily arrange to pass the worker thread additional data of your choosing.
|Last Updated ( Wednesday, 29 August 2012 )|