Improving Silverlight Application Performance
- The difference between synchronous and asynchronous programming techniques
- How to make asynchronous calls to a Web service
- To download large objects asynchronously by using the HTTP Downloader
This lesson will introduce the ability to play various types of multimedia sources in a Silverlight application.
Synchronous vs. Asynchronous Processing
Computers that contain a single processor are only capable of performing a single task at a time. Most laptops that are running Windows, for example, have a single processor (CPU) and are only capable of performing a single task on the computer at a time. If that is the case, how does an elaborate operating system like Windows seemingly perform many concurrent tasks as well as host multiple applications in memory simultaneously with each application also performing tasks? The answer is that the operating system manages the time that the processor allocates to performing each task very efficiently. The operating system allocates an incredibly small slice of the processor's time to each application and task that is in memory. The applications and tasks are then cycled through with each performing a small amount of work. The processor cycles through the applications and tasks very quickly as to give the illusion that multiple tasks are being performed simultaneously.
Each application that is loaded into memory is referred to as a process. Each process typically attempts to perform a single task and so each process is assigned a single thread of execution (a slice of the processor's time) to use to complete the task. Most code is written to perform a single task at a time and to complete the task at hand before continuing on to execute the next task. This type of processing is referred to as synchronous processing. In most scenarios, synchronously executing code is accomplished very quickly and will suffice. Additionally, in most scenarios, most tasks being performed in code are reliant upon the previous task being completed before the task can be performed. For example, when querying a database, the query cannot be executed until a connection to the database is open. Hence the database commands must be performed in a particular order and synchronous processing is a perfect fit.
However, occasionally tasks are performed in code that are not reliant upon other tasks to be completed first. When tasks that can be performed independently can be identified, it would increase performance if the task could be performed in parallel to other tasks being performed by the application. This is possible by intentionally writing code that spawns another thread of execution so that the process (application) is allocated more than one slice of the processor's time. If multiple tasks are performed in parallel by an application, the application is said to be multithreaded (utilizes more than a single thread to perform its work). When tasks are performed in parallel, the call in code from the initial thread that initiates a task to be performed on another thread doesn't have to wait around for the additional task to complete before continuing on. If it did wait for additional threads to complete their work, the tasks would still be performed in series and there would be no benefit to utilizing multiple threads of execution.
When an additional task is performed in parallel on a separate thread, it is referred to as asynchronous processing. Asynchronous processing is more complex than synchronous processing. When a task is performed synchronously, the code that initiated the synchronous task waits on the task to complete before continuing. However, when a task is performed asynchronously, the code that initiated the asynchronous task continues execution immediately and does not wait on the asynchronous task to complete. So what happens when the asynchronous task completes?
When code initiates an asynchronous task, it also directs the asynchronous task to execute a method or function (known as a callback method) once it completes its work.
Asynchronous processing is a perfect fit for time consuming tasks that can be performed independently. Asynchronous processing is being utilized in most of the recent Web technologies. For example, AJAX stands for Asynchronous JavaScript and XML. In AJAX, an asynchronous call is made to the server behind the scenes. The call is independent of the thread that is processing the Web page and interacting with the user, hence UI performance is increased and the user does not have to wait on the call to the server to complete but will see the results when the results are returned.
Background Worker Process
The .NET Framework provides facilities to spawn multiple threads of execution through the classes in the System.Threading namespace. Currently, Silverlight also includes a System.Threading namespace, however the classes included in the namespace have not yet been implemented in Silverlight. Hence, the plans are in place to make Silverlight multithreaded but it won't be functional in Silverlight until a later release.
Silverlight does currently perform some asynchronous processing through the use of a background worker process. However, the background worker process is not currently controllable. Additionally, the background worker process executes tasks using a different thread of execution from the thread that manages the user interface and Silverlight, currently, does not allow cross-thread calls.
There are a few hacks being used on the Web to trick Silverlight into utilizing multiple threads, however multiple threads of execution are not currently supported by the default Silverlight functionality.
Asynchronously Calling a Web Method
As mentioned above, Silverlight currently prohibits cross-thread calls but does utilize a background worker process so that asynchronous calls can be made; particularly to Web methods. No modifications need to be made to an ASP.NET Web service or WCF service that is being called asynchronously. The code being called doesn't care if its called synchronously or asynchronously, it simply executes when called. The calling code, however does require slight modification.
The example shown below was utilized in the previous module to implement some security. However, when you click the button, there is a noticeable delay while the Web service is called and the Web method is executed. The Silverlight page resembles the following figure.
The code in the Page.xaml.cs file that calls the Web method, does so synchronously as shown below.
public void GetPetInfo(object o, MouseEventArgs e)
{
PISCLINQ.localhost.PetService svc = new PISCLINQ.localhost.PetService();
IEnumerable<string> pets = from petInfo in
svc.GetPetInfo(user.UserName, user.Password)
select petInfo;
// Display the results.
foreach (string pet in pets)
{
tbOutput.Text += pet;
}
}
When calling an ASP.NET Web service or WCF service by adding a Web Reference to a project in Visual Studio, Visual Studio creates a proxy class that handles communication between your application and the Web method and handles serializing and deserializing data. The proxy class created includes methods for calling a Web method both synchronously and asynchronously. Hence the only changes that really need to take place are in the calling code. The calling code shown above is converted to make the call asynchronously as shown below.
public void GetPetInfo(object o, MouseEventArgs e)
{
PISCLINQ.localhost.PetService svc = new PISCLINQ.localhost.PetService();
AsyncCallback asyncCall = new AsyncCallback(CallbackMethod);
svc.BeginGetPetInfo(user.UserName, user.Password, asyncCall, svc);
}
The code above may look a bit confusing at first. The second line of code in the method creates an instance of a delegate designed to serve as a callback method. The third line makes the asynchronous call to the Web method and passes the input parameters as well as a reference to the callback method that the task will call when it completes, and a reference to the Web service instance being utilized. When the task completes, because the call is made asynchronously, Silverlight will keep the instance of the Web service proxy in memory and the callback method can reference it to retrieve the resulting value of the method call. The callback method is shown below.
private void CallbackMethod(IAsyncResult asyncResult)
{
// Create an instance of the WebService
localhost.PetService svc =
(localhost.PetService)asyncResult.AsyncState;
// Get the Result of the WebMethod by calling
// the end method of the proxy class
IEnumerable<string> pets = from petInfo in svc.EndGetPetInfo(asyncResult)
select petInfo;
// Display the results.
foreach (string pet in pets)
{
tbOutput.Text += pet;
}
}
The LINQ code was moved to the callback method where it will be processed after the Web method call has completed.
The HTTP Downloader
Silverlight includes another class that is used to directly download resources from a Web server, the HTTP Downloader. The name of the HTTP Downloader is actually "Downloader" but the class is commonly referred to as the HTTP Downloader as that term better describes its use. The Downloader is best suited to directly downloading larger resources from a Web server that may take time to download. The calls made by the Downloader are asynchronous. The code below is used to download a move named LondonNewsCast.wmv.
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace LondonVideo
{
public partial class Page : Canvas
{
public void Page_Loaded(object o, EventArgs e)
{
// Required to initialize variables
InitializeComponent();
// Download the media.
Downloader dl = new Downloader();
dl.Completed += new EventHandler(dl_Completed);
dl.Open("GET", new Uri("LondonNewsCast.wmv", UriKind.Relative));
dl.Send();
}
void dl_Completed(object sender, EventArgs e)
{
Downloader dl = (Downloader)sender;
mediaLondon.SetSource(dl, "");
}
}
}In the code above, an instance of the Downloader class is created. Just as with an asynchronous call to a Web method, a callback must be supplied to the call. In this code, the Completed event is wired into the dl_Completed handler.
Lab: Improving Performance
In this lab, you will use the HTTP downloader to download content and call Web methods asynchronously.
Improving Silverlight Application Performance Conclusion
In this lesson of the Silverlight tutorial, you
- Reviewed synchronous and asynchronous processing techniques
- Called Web methods asynchronously
- Utilized the HTTP Downloader
