Code Focused

Visual Basic Improvements in Visual Studio 11

Visual Basic development in Visual Studio 11 offers asynchronous methods, iterators, call hierarchy, the Global keyword and Windows 8 Metro-based applications.

One of the primary themes in Windows 8 is availability over a wide range of hardware platforms, from low-power smartphones to portable tablets to desktop PCs. Windows 8 will have the Metro mode -- very similar in behavior and appearance to Windows Phone 7 -- that will run across all the platforms, plus the Desktop mode that will run only on those platforms that can support it.

The requirement of Metro to remain responsive on low-power devices that might have significantly less computing power than traditional Windows 7 desktops leads Visual Basic 11 (and C# 5.0) to have a strong emphasis on delivering a responsive user experience through asynchronous methods. This emphasis is seen in the introduction of the Async and Await keywords in Visual Basic (async and await in C#), and the iterator construct in Visual Basic to bring parity with iterators introduced into C# in Visual Studio 2005.

Async and Await
First introduced in Visual Studio 2010 as the Async CTP, the Async modifier flags a method or lambda as an asynchronous method. When method execution encounters the Await operator on a task, execution suspends and immediately returns to the calling method. When the asynchronous task completes, the Async method is resumed at the point from which it suspended. No longer are separate task completion callback methods needed; as a result, asynchronous code is structured very similarly to standard synchronous code. This makes it much easier to add asynchronous code in areas where it was previously difficult, such as loops and the exception-handling Try block.

The Async and Await operators don't perform multi-threading. These operators simply allow the compiler to structure the execution path such that the execution thread isn't blocked when an asynchronous method is called. In other words, the application remains single-threaded but that thread is more productive and as a result, the application remains more responsive. The Async and Await operators are available to any Visual Basic 11 application; they aren't limited to the newer Metro-style applications.

Async subroutines should be used for event handlers, and Async functions for all other tasks. Functions must return Task or Task(Of TResult). Only ByVal parameters are permitted into the Async method; ByRef parameters are prohibited to ensure that parameter values don't change while the method is suspended. Microsoft recommends that the name of any Async function or subroutine end in "Async" to designate it as such.

The advantage of asynchronous over synchronous code is well known to most developers. To illustrate the difference in Visual Basic 11 coding, I've prepared a simple Windows Forms application, shown in Figure 1. The application displays four Web pages in a single screen in order to demonstrate latency. The Web page source is retrieved using either the HttpClient's synchronous Get method or its asynchronous GetAsync method, and used to populate the Web browser control's document object to display the page. The larger MSDN homepage is displayed in Pages 1 and 3 on the left, and the smaller Bing homepage is displayed on the right in pages 2 and 4. Separate HttpClient calls are used for each page.


[Click on image for larger view.]
Figure 1. Synchronous vs. Asynchronous demo.

As expected, when the "Load Pages Synchronous" button is clicked, the screen is unresponsive. The code in Listing 1 is executed, requiring 2.469 seconds until control is returned to the user by displaying all four pages at once. When the "Load Pages Asynchronous" button is clicked, the asynchronous version is executed, requiring only 0.016 seconds to return control to the user, 154 times faster in this case. The times vary slightly with each run, but the pattern is consistent. Visually, control is returned to the user, then the two smaller Bing pages on the right are displayed, a slight pause, then the two larger MSDN pages on the left appear. The screen remains responsive throughout this process.

The asynchronous version of the code is virtually identical to Listing 1, changed only by replacing the UpdateWebControlSync method with the UpdateWebControlAsync function.

You can see in Listing 2 how the Async and Await operators simplify the code by eliminating the need for a callback function. Literally the only changes needed to make the method asynchronous were to add the Async modifier in the method definition, add the Await modifier to the HttpClient call and use its asynchronous GetAsync function, rather than the synchronous Get function.

The following code asynchronously loads Page 2 by converting a standard button click handler into an Async subroutine:

Private Async Sub btnButtonAsync_Click(sender As Object, e As EventArgs) Handles btnButtonAsync.Click
  wb2.DocumentText = ""
  Dim response = Await New System.Net.Http.HttpClient().GetAsync(New System.Uri(bingURL))
  Dim pageHTML = response.Content.ReadAsString
  wb2.Document.Write(pageHTML)
End Sub

Another variation is to use the AddHandler method in the constructor to hook up an asynchronous multi-line lambda for the button click event:

AddHandler btnLambdaAsync.Click, Async Sub(sender, e)
  wb2.DocumentText = ""
  Dim response = Await New System.Net.Http.HttpClient().GetAsync(New System.Uri(bingURL))
  Dim pageHTML = response.Content.ReadAsString
  wb2.Document.Write(pageHTML)
End Sub

You need to pay attention to asynchronous behavior when choosing how to structure your code. Had the UpdateWebControlAsync been written to return the HTML as a string result and have the calling method set the WebBrowser control's Document property, it would've failed; the calling method would've resumed execution and tried to set the Document property while the HttpClient GetAsync method was still in process.

This anti-pattern is shown in Listing 3 as an example of an incorrect use of an Async method. When IncorrectCallerAsync is executed, the "Method completed:" message is displayed a few seconds before the "HTML Received:" message. The "Page 1 Updated:" message is never displayed due to the check for TaskStatus.RanToCompletion; the status returned was TaskStatus.WaitingForActivation. In this example, accessing the HTMLtask.Result prior to its completion consistently locked up the application. See the code download (available at VisualStudioMagazine.com/Kunk0112) for the sample application.

Not every method can be used with the Await modifier; it must implement the GetAwaiter method in the System.Windows.Threading namespace. In practical terms, this means you need an Async version of the latency-capable method you want to await. The Microsoft .NET Framework does enable you to call any method asynchronously, but those methods without GetAwaiter are substantially more involved to implement without the Await modifier. For more on this, see the MSDN Library page, "Calling Synchronous Methods Asynchronously."

Iterators
While Async and Await provide general asynchronous functionality, iterators provide easy-to-code asynchronous operations in the specific case of processing items in a collection as they become available. Populating the collection will take essentially the same amount of time as without iterators, but each element can become immediately available to the calling method as it's created. Which elements are returned is controlled by the developer through the use of the Yield statement.

By immediately updating the UI, the application will appear more responsive with the use of iterators (see Listing 2). For a more detailed explanation of iterators, see my online On VB column, "Understanding Iterators: Concepts, Benefits and Functionality."

Call Hierarchy
Navigation through the source code is easier for Visual Basic 11 with the new Call Hierarchy feature, which is available for any method, property or constructor. This feature displays calls made into the selected method and calls made by the selected method, with drill down into any of the called methods. Call Hierarchy is available on the context menu within the method source, or by keyboard with Ctrl+K, Ctrl+T. The Call Hierarchy display for the demo program is shown in Figure 2 (the relevant portion of the right-click context menu is inset).


[Click on image for larger view.]
Figure 2. The Call Hierarchy display for the DoLoadPagesAsync method of the demo program.

Selecting an item displays on the right the Call Sites that show where the calls occur. Multiple methods can be displayed in the Call Hierarchy window; each is considered a separate removable root. Double-click a Call Site to go to that line of source code.

Global Keyword
Namespaces can get confusing in Visual Basic, perhaps more so than in C#. This is particularly true when an assembly contains a namespace identical to one contained in the .NET Framework namespaces. To address these name collisions, Visual Basic 11 now includes a Global keyword that represents the outermost level of the .NET Framework class library. Thus, Global.System.IO.Path can be easily distinguished from SomeApp.System.IO.Path. The Global keyword cannot be nested in a namespace declaration. For more information, see the MSDN Library page, "Namespaces in Visual Basic."

The Windows 8 Development Environment
Development in Windows 8 is targeted either to the Desktop mode for Windows 8 and earlier versions of Windows, or the new Metro mode for applications targeted specifically to Windows 8, including any new Metro-only devices. For a comparison of the Windows 8 Desktop mode to the Metro mode and how that impacts developers in a non-language-specific way, see my online On VB column, "Developer Recommendations from BUILD." Desktop-mode applications should be optimized for a larger screen, keyboard and mouse; Metro-mode applications should be optimized for a smaller screen and touch capability.

JavaScript Can Call Managed Code
Windows 8 Metro applications are Windows client applications, not Web applications. Windows 8 Metro applications execute utilizing the new Windows Runtime (WinRT), which essentially replaces Win32 as the provider of low-level services to the .NET Framework. WinRT is directly accessible from a Windows Metro application for access to system services.

There are two types of apps that can be developed for Metro mode. First is XAML interface applications with managed language codebehind such as C, C++, C# or Visual Basic. Second, and new in Windows 8, is an HTML interface application with a JavaScript codebehind. Note this is still a Windows application, not run in a browser. When opening a new project in Visual Studio 11, you'll see JavaScript as a first-class language with available templates alongside Visual C#, SQL Server, Visual C++, Visual F# and Visual Basic.

Perhaps one of the most exciting aspects of a Windows 8 Metro JavaScript application is that it can call a library written in Visual Basic or any other managed language. The Metro profile of the .NET Framework limits the methods available to the managed code library to those considered safe or appropriate for mobile devices; for example, the System.IO.File class isn't defined. Within that restriction, it's a great way to share managed code libraries between Desktop applications and Metro applications to reduce the amount of JavaScript required for sophisticated applications.

Listing 4 is a simple HTML page that displays messages by calling the VBMetroLibrary JavaScript function, which is shown in Listing 5. The Visual Basic VBMetro WinMD library code is shown in Listing 6. See the code download for the sample application.

Notice that the Visual Basic class in Listing 6 must be NotInheritable ("sealed" in C#). Managed code libraries must set the Application type to WinMD on the project properties Application tab in order to be consumed by Windows 8 JavaScript; the default application type of Class Library can't be referenced.

Other Enhancements
There are significant enhancements outside of the Visual Basic language that will help deliver a better experience to the Visual Basic developer in Visual Studio 11.

Visual Studio 11 contains full-featured editors for JavaScript, HTML, XML, XAML, CSS, C#, Visual Basic, C++ and High Level Shading Language for DirectX (HLSL), with JavaScript and C++ seeing the most improvements. Many features of the popular Visual Studio Gallery Productivity Power Tools (available at bit.ly/g4fUGG) have been incorporated into Visual Studio 11.

The .NET Framework 4.5 includes numerous enhancements. For a comprehensive list of .NET Framework 4.5 enhancements, see bit.ly/nvZ2nI, but here's a handful:

  • The core Framework provides regular expression engine timeout, automatic NGen (native code compilation) based on assembly usage, generics in the Managed Extensibility Framework (MEF), improved zip compression, and enhanced performance-retrieving resources.
  • ASP.NET enhancements include HTML5 form types, MVC-like model binders in Web Forms, script combining and minification, WebSockets support, asynchronous access to HTTP requests and modules and handlers, and unobtrusive JavaScript in client validation scripts.
  • Networking enhancements include the new System.Net.Http and System.Net.Http.Headers namespaces.
  • Windows Presentation Foundation enhancements include a native Ribbon control, the new INotifyDtaErrorInfo to support both synchronous and asynchronous data validation and repositioning data as values change.
  • Windows Communication Foundation enhancements include support for Contract-First development, WebSockets support, ChannelFactory caching and binary encoder compression support.
  • Windows Workflow Foundation enhancements include state machine workflows, new document outline view, C# and Visual Basic expressions by project type, and the new Workflow-Identity class to map a persisted workflow to its definition.

Visual Studio 11 and Visual Basic 11, along with the .NET Framework 4.5, are heavily focused on providing a consistently responsive UI experience across smaller and less powerful devices, through the availability of the Async and Await modifiers, iterators and additional Async input/output methods. Beyond this focus, there are many features that will appeal to every .NET developer. If you haven't already, I recommend that you try out the Visual Studio 11 Developer Preview. Scott Hanselman's blog post with instructions for installing it as a bootable (dual boot with Windows 7) Virtual Hard Drive (VHD), as I did, is available here. Explore and enjoy!