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
- AddEffectAsync Adds an audio or video effect.
- CapturePhotoToStorageFileAsync Captures a photo to a storage file.
- CapturePhotoToStreamAsync Captures a photo to a random-access stream.
- ClearEffectsAsync Removes all audio and video effects from a stream.
- InitializeAsync Initializes the MediaCapture object, using default settings.
- InitializeAsync(MediaCaptureInitializationSettings) Initializes the MediaCapture object.
- StartPreviewAsync Starts preview.
- StartPreviewToCustomSinkAsync(MediaEncodingProfile, IMediaExtension) Starts previewing to a custom media sink.
- StartPreviewToCustomSinkAsync(MediaEncodingProfile, String, IPropertySet) Starts previewing to a custom media sink.
- StartRecordToCustomSinkAsync(MediaEncodingProfile, IMediaExtension) Starts recording to a custom media sink.
- StartRecordToCustomSinkAsync(MediaEncodingProfile, String, IPropertySet) Starts recording to a custom media sink.
- StartRecordToStorageFileAsync Starts recording asynchronously to a storage file.
- StartRecordToStreamAsync Starts recording to a random-access stream.
- StopPreviewAsync Stops preview.
- StopRecordAsync Stops recording.
Asynchronous Functions of StorageFile
- CopyAndReplaceAsync Asynchronously replaces the specified storage file with a copy of the current file.
- CopyAsync(IStorageFolder) Asynchronously creates a copy of the storage file and stores it in the specified storage folder.
- CopyAsync(IStorageFolder, String) Asynchronously creates a copy of the storage file, gives it the specified filename, and stores it in the specified storage folder.
- CopyAsync(IStorageFolder, String, NameCollisionOption) Asynchronously creates a copy of the storage file, gives it the specified filename, and stores it in the specified storage folder. The method also specifies what to do if a file with the same name already exists in the specified folder.
- CreateFileForTransferAsync (String, StreamReference) Asynchronously creates a new file to transfer to another application.
- CreateFileForTransferAsync (String, StreamReference, FileDataRequestedHandler) Asynchronously creates a new file to transfer to another application.
- DeleteAsync Asynchronously deletes the storage file.
- DeleteAsync(StorageDeleteOption) Asynchronously deletes the storage file by using the specified delete option.
- GetFileFromPathAsync Asynchronously retrieves a storage file based on the specified file system path.
- GetFileFromUriAsync Asynchronously retrieves a file based on the specified Uniform Resource Identifier (URI).
- GetThumbnailAsync(ThumbnailMode) Asynchronously retrieves the thumbnail that is associated with the storage file.
- GetThumbnailAsync(ThumbnailMode, UInt32) Asynchronously retrieves the thumbnail that is associated with the storage file, scaling it to the specified size.
- GetThumbnailAsync(ThumbnailMode, UInt32, ThumbnailOptions) Asynchronously retrieves the thumbnail that is associated with the storage file, scaling it to the specified size.
- MoveAndReplaceAsync Asynchronously moves the current storage file from its location and uses it to replace the specified storage file.
- MoveAsync(IStorageFolder) Asynchronously moves the storage file to the specified storage folder.
- MoveAsync(IStorageFolder, String) Asynchronously moves the storage file to the specified folder, and gives the file the specified filename.
- MoveAsync(IStorageFolder, String, NameCollisionOption) Asynchronously moves the storage file to the specified folder, and gives it the specified filename. The method also specifies what to do if a file with the same name already exists in the specified folder.
- OpenAsync Asynchronously opens the storage file and retrieves a stream object for accessing the file contents.
- OpenForReadAsync Asynchronously opens the storage file and retrieves a stream object for reading the file contents.
- RenameAsync(String) Asynchronously renames the storage file.
- RenameAsync(String, NameCollisionOption) Renames the storage file, and specifies what to do if a file with the same name already exists in the current folder.
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.