Creating and Managing Asynchronous Operations in the Windows Runtime (WinRT)

CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Windows runtime is designed to provide a platform to create language independent metro style applications. Metro style applications combine the benefit of the web by extending the browser experience to the rich Windows experience. Windows runtime uses API metadata (.winmd files) and follows the ECMA-335 framework. The WinRT also provides a collection of patterns for creating and managing asynchronous operations.

Asynchronous Programming

With asynchronous programming you can start long running process in the background without blocking UI thread. The result of the background process can be retrieved at a later period of time. Explicit thread management or direct interaction with the underlying operation is not required. Windows runtime provides features of asynchronous functions like MediaCapture and StorageFile. To adhere to the concept asynchronous functions end with “Async”.

Asynchronous Functions of MediaCapture

Asynchronous Functions of StorageFile

The Windows Runtime provides asynchronous patterns specific to each programming language such as Javascript, C#, VB.NET, C++. This article concentrates on the C# implementation of the asynchronous functions.

Asynchronous Patterns with C#

The basic building block of asynchronous programming in C# is the Task class under the System.Threading.Tasks namespace and the await operator. By Action delegates you may provide code that executes asynchronously. Calling the asynchronous method is simple, the only difference is that to manage Task you use await operator. The await operator actually suspends the execution until the task is complete while control returns to the caller of the current method.

The code snippet below shows how to create an asynchronous temporary file using the CreateFileAsync method.

using System.Diagnostics;
using Windows.Storage;
using Windows.Networking.BackgroundTransfer;



async Task CreateAsyncTempFile()
{
                Uri uri = new Uri("http://www.google.com");
                IStorageFolder fileTemp = Windows.Storage.ApplicationData.Current.TemporaryFolder;
    StorageFileRetrievalOperation sfro = fileTemp.CreateFileAsync("tempfile.txt");
    Task<StorageFile> tasks = op.StartAsTask<StorageFile>();
    var tempFile = await task;
    Debug.WriteLine("Temp file Created at: " + fileTemp.Path);
}
 

The CreateAsyncTempFile method blocks Task until StorageFileRetrievalOperation has completed. While task runs in the background, the await operator transfers handle to the caller and on task completion execution is transferred back to fileTemp assignment in the CreateAsyncTempFile method. Control is not transferred to caller until first await operator is encountered. Asynchronous method should be written only when it does not have to do lot of work or perform blocking calls before its first await or between await operators. Instead, more intensive work or blocking calls from the thread should be put in the thread pool using the Task.Run method. The return type of asynchronous method can be only void, Task or Task<T>.

Progress and Completion Handling in C#

The progress of asynchronous operations can be tracked by notification delegate. The code below shows how to download a web page asynchronously to a file by using the StartDownloadAsync function with progress and completion notifications.

using System.Diagnostics;
using Windows.Storage;
using Windows.Networking.BackgroundTransfer;



async Task DownloadAsync()
{
    Uri uri= new Uri("http://www.google.com");
    IStorageFolder tmpFolder = Windows.Storage.ApplicationData.Current.TemporaryFolder;
    var tmpFile = await tmpFolder.CreateFileAsync("tmpfile.txt");
    var bgDownloader = new Windows.Networking.BackgroundTransfer.BackgroundDownloader();
    DownloadOperation dop = backgroundDownloader.StartDownloadAsync(uri, tmpFile);
    dop.Progress = new AsyncActionProgressHandler<BackgroundDownloadProgress>(DownloadProgressEventHandler);
    dop.Completed = new AsyncActionWithProgressCompletedHandler<BackgroundDownloadProgress>(DownloadCompletedHandler);



    await dop.StartAsTask();
}
void DownloadProgressHandler(
    IAsyncActionWithProgress<BackgroundDownloadProgress> action,
    BackgroundDownloadProgress p)
{
    Debug.WriteLine("Bytes received:" + p.BytesReceived);
}



void DownloadCompleteHandler(IAsyncActionWithProgress<BackgroundDownloadProgress> dop)
{
    if (dop.Status == AsyncStatus.Error)
    {
        Debug.WriteLine("Error " + dop.ErrorCode);
    }
    else if (dop.Status == AsyncStatus.Canceled)
    {
        Debug.WriteLine("Canceled");
    }
    else if (dop.Status == AsyncStatus.Completed)
    {
        Debug.WriteLine("Download Completed");
    }
}
 

Asynchronous task is managed by StartDownloadAsync, which returns DownloadOperation. Progress handler with progress and intermediate result objects is called as asynchronous task updates to report. When the task completes, the completed handler is called and you can check the result of the task by inspecting the Status property.

Anonymous Delegates in C#

By providing anonymous delegates, detailed information about the outcome of an asynchronous operation and progress can be tracked. The following code snippet shows how to download a web page asynchronously, with progress and completion notifications delegated anonymously.

using System.Diagnostics;
using Windows.Storage;
using Windows.Networking.BackgroundTransfer;



async Task AnonymousDownloadDelegateAsync()
{
    Uri uri= new Uri("http://www.google.com");
    IStorageFolder tmpFolder = Windows.Storage.ApplicationData.Current.TemporaryFolder;
    var tmpFile = await tmpFolder.CreateFileAsync("tmpfile.txt");
    var bgDownloader = new Windows.Networking.BackgroundTransfer.BackgroundDownloader();
    DownloadOperation dop = backgroundDownloader.StartDownloadAsync(uri, tmpFile);
    dop.Progress = delegate(
        IAsyncActionWithProgress<BackgroundDownloadProgress> action,
        BackgroundDownloadProgress progress)
    {
        Debug.WriteLine("Bytes received:" + progress.BytesReceived);
    };



    dop.Completed = delegate(IAsyncActionWithProgress<BackgroundDownloadProgress> completeOp)
    {
        // Perform actions based on the completion status.
        if (completeOp.Status == AsyncStatus.Error)
        {
            Debug.WriteLine("Error " + dop.ErrorCode);
        }
        else if (completeOp.Status == AsyncStatus.Canceled)
        {
            Debug.WriteLine("Canceled");
        }
        else if (completedOp.Status == AsyncStatus.Completed)
        {
            Debug.WriteLine("Download Completed");
        }
    };
    await dop.StartAsTask();
}
 

Conclusion

In asynchronous programming, the programmer initiates the operation and subsequently registers a callback, which will be invoked when the results are available. As there is no waiting time, a programmer can do useful tasks while the operation is in progress, such as service the message loop or initiate other asynchronous operations. In Windows 8, asynchronous operations are ubiquitous, and WinRT offers a new programming model for dealing with asynchrony in a consistent way.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read