Hello and welcome to today's article. With this article I plan to show you how easy it is to Do Async programming with VB.NET 2012 and Windows 8. Let's get started.
The best way to learn is always with an example. Our little project's aim is to show all folders inside the Pictures Library. After that, we will show all the subfolders within the selected folder, and finally all the files inside a particular subfolder. Doesn't sound too complicated, but it can be especially if you want to achieve all of this through the use of Async and Await.
Asynchrony is crucial to any app that depends on certain tasks that may cause bottlenecks or block the rest of your program, or worse, freezing. So in fact, it makes applications respond quicker while running several tasks in the background.
Async and Await
Quoted from MSDN :
"If you specify that a method is an async method by using an Async or async modifier, you enable the following two capabilities.
1. "The marked async method can use Await or await to designate suspension points. The await operator tells the compiler that the async method can't continue past that point until the awaited asynchronous process is complete. In the meantime, control returns to the caller of the async method.
2. "The suspension of an async method at an await expression doesn't constitute an exit from the method, and finally blocks don't run.
"The marked async method can itself be awaited by methods that call it.
"An async method typically contains one or more occurrences of an await operator, but the absence of await expressions doesn't cause a compiler error. If an async method doesn't use an await operator to mark a suspension point, the method executes as a synchronous method does, despite the async modifier. The compiler issues a warning for such methods."
Design your Main screen to resemble figure 1. There should be three ListBoxes, three TextBlocks ( Folders, Subfolders, Files ) and one Button.
Figure 1 - Our Design
Not much code, but it doesn't mean that it is simple. First, let's declare the arrays we will use in this example:
Private arrFolderNames() As String 'Holds All Folder Names Private arrSubFolderNames() As String 'Holds All Subfolder Names Private arrFileNames() As String 'Holds All File Names
Add the next code behind the Browse Folders button:
Private Async Sub Button_Click_1(sender As Object, e As RoutedEventArgs) 'Method Is Made Async Dim RootFolder As StorageFolder = KnownFolders.PicturesLibrary 'Use Pictures Folder As Our Root Folder 'IReadOnlyList represents a read-only collection of elements that can be accessed by index. Dim FolderList As IReadOnlyList(Of IStorageItem) = Await RootFolder.GetItemsAsync 'Gets a list of top-level files and sub-folders inside the current folder. Dim Counter As Integer 'Counter For Number Of Items For Each folder In FolderList 'Loop Through Each Item Found If TypeOf folder Is StorageFolder Then 'If We Found A StorageFolder lstFolders.Items.Add(folder.Name) 'Add folder name to ListBox ReDim Preserve arrFolderNames(Counter) 'Redimension Array arrFolderNames(Counter) = folder.Path 'Store Each Folder's path Inside Array Counter += 1 'Increment Counter End If Next End Sub
Figure 2 - Folders Inside the Pictures Library
First, we made the Sub procedure Async capable by including Async in front of the Sub keyword. We created our rootfolder, which equates to KnownFolders.PicturesLibrary. KnownFolders provides access to common locations that contain user content. Remember this is ultimately a Windows 8 Store program so it must be compatible with both PC and cellphones. If you'd rather have C:\ or a different folder as a rootfolder, you'd have to make a Desktop application.
We then obtained a list of items returned by the GetItemsAsync method of our StorageFolder object. We loop through each item and determine whether or not it is a Folder. If in fact it is a StorageFolder, we add its name to the lstFolders Listbox and obtain and store its path into our arrFoldernames array. This path we store here will be used by the next method(s) to obtain its subfolders and files. This is easier, otherwise we would have to go through this whole process again, and recreate a rootfolder object.
Add the following code for the Folders Listbox's SelectedIndexChanged event:
Private Async Sub lstFolders_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles lstFolders.SelectionChanged 'Method Is Async 'Gets a StorageFolder that represents the folder at the specified file-system path. 'Gets All Folders From selected folder Dim SubFolder As StorageFolder = Await StorageFolder.GetFolderFromPathAsync(arrFolderNames(lstFolders.SelectedIndex)) 'IReadOnlyList represents a read-only collection of elements that can be accessed by index. Dim SubFolderList As IReadOnlyList(Of IStorageItem) = Await SubFolder.GetItemsAsync 'Gets a list of top-level files and sub-folders inside the current folder. Dim Counter As Integer 'Counter For Each Folder In SubFolderList 'Loop through Items If TypeOf Folder Is StorageFolder Then 'If StorageFolder lstSubFolders.Items.Add(Folder.Name) 'Add To Sub Folder ListBox ReDim Preserve arrSubFolderNames(Counter) 'Redimension SubFolder array arrSubFolderNames(Counter) = Folder.Path 'Store Each Sub Folder's Path Counter += 1 End If Next End Sub
Figure 3 - Subfolders
This code is almost verbatim the same as the previous code segment. In essence, it does the same thing. Instead of creating a RootFolder object, we make use of the GetFolderFromPathAsync method of the StorageFolder class. This gives us the path of the current selected folder, and now we can loop through its contents and enumerate the contents inside lstSubFolders
Add the last code segment:
Private Async Sub lstSubFolders_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles lstSubFolders.SelectionChanged Dim SubFolder As StorageFolder = Await StorageFolder.GetFolderFromPathAsync(arrSubFolderNames(lstSubFolders.SelectedIndex)) Dim SubFolderList As IReadOnlyList(Of IStorageItem) = Await SubFolder.GetItemsAsync Dim Counter As String For Each File In SubFolderList If TypeOf File Is StorageFile Then lstFiles.Items.Add(File.Name) ReDim Preserve arrFileNames(Counter) arrFileNames(Counter) = File.Path Counter += 1 End If Next End Sub
Figure 4 - Files
The only thing worth noting here is that we continuously built the folder and file path. Here we got the Folder paths from the arrSubFolderNames array, and simply retrieve the files inside.
If we were to run this example now, we might get an error explaining that we haven't added the capability for our program to access the Pictures Library. We have to give our program permission to scratch around in there. We can do this by opening the application's manifest, clicking on the Capabilities tab, and selecting the PicturesLibrary. Figure 5 shows the application Manifest's settings.
Figure 5 - Application Manifest
For more information regarding Async and Await, have a read through here .
Well, short and sweet. I hope you have benefited from this article. Until next time, asta la vista!
About the Author: Hannes du Preez is a Microsoft MVP for Visual Basic for the fifth year in a row. He is a trainer at a South African-based company providing IT training in the Vaal Triangle. You could reach him at hannes [at] ncc-cla [dot] com