Visual Studio 11 Beta Is Here!

As you may have seen in Jason’s blog, Visual Studio 11 Beta is available for download today, including the Beta version of C# 5.0!  If you’ve tried out the Visual Studio 11 Developer Preview, you already know that this is an exciting release, with two huge new features for C# developers: async methods and support for creating Windows 8 Metro style apps.  However, with Beta comes even more goodness, with support for caller info attributes, aswell as a host of async perf improvements and async unit-testing support.

The best way to see what’s new in Visual Studio 11 is to dive in and try it yourself.  However, if you’re curious to know what you’re getting, read on!

Async methods (the await keyword)

As you migrate your desktop applications to mobile phones and tablets, you’re increasingly faced with the realities of network latency, especially given a reliance on cloud services running in distant datacenters.  At the same time, your users expect far more responsiveness from these applications, with the bar set by smooth touch UIs that never drop a frame.

The way out of this conundrum up to now has been asynchronous programming and the use of callbacks.  However, while callbacks can work for very simple methods, you quickly fall into the pit of despair for code that’s of any reasonable length or complexity, giving up the core control flow constructs you’ve trusted for years – chained callback methods and for loops don’t mix!

There has to be a way out of this mess, and there is – async methods in C# 5.0, powered by the await keyword:

public async Task<int?> SumPageSizesAsync(IList<Uri> uris) {
    try {
        int total = 0;
        var client = new HttpClient();
        client.MaxResponseContentBufferSize = 10000000;
        foreach (var uri in uris) {
            statusText.Text = string.Format("Found {0} bytes ...", total);
            var data = await client.GetByteArrayAsync(uri);
            total += data.Length;
        }
        statusText.Text = string.Format("Found {0} bytes total", total);
        return total;
    }
    catch (Exception) {
        statusText.Text = "Error!";
        return null;
    }
}

By marking your method with the async keyword, the C# compiler transforms it into a resumable async method that can pause execution whenever it sees the await keyword by returning control to the caller.

  • If this is a client app, control returns to your caller at each await, and then to its caller, and so on, until you’ve freed up the UI thread, which keeps your app responsive.
     
  • If you’re writing a server, returning to the caller frees up the thread handling the current request, ensuring that thread is available to process other requests and increasing your scalability.

In either case, once the operation you’re awaiting completes, your method wakes up, resuming execution right where it left off, even if you were within a foreach loop or a try-catch block.  When execution is paused, you can even hit F10 to Step Over at the await, with the debugger returning you to the following line after the awaited operation completes.

This is just a brief peek at Async – if you’ve yet to try it, be sure to check out the Asynchronous Programming Developer Center for samples, videos and more to get started.  However, if you have been using Async for a while now through our previous preview releases, you’ll be excited to see what’s new in Beta!

Since the Developer Preview, we’ve done work to further improve the perf of async methods, reducing allocations to ensure you can feel comfortable using async methods throughout your application, wherever you need them.  However, such comfort also requires that you can trust your async methods to continue working as expected as you continue to make changes elsewhere in your app.  To this end, MSTest and xUnit.net now support async methods directly, ensuring that the test runner waits for the async method to fully complete:

[TestMethod]
public async Task Test1() {
    var x = await Engine.GetSevenAsync();
    Assert.AreEqual(x, 6);
}

[Xunit.Fact]
public async Task Test2() {
    var y = await Engine.GetSevenAsync();
    Assert.AreEqual(x, 6);
}

Caller Info Attributes

One language feature that’s making its debut in Visual Studio 11 Beta is caller info attributes.  These attributes let a method accept implicit optional parameters intended to receive a line number, a file path or a member name.  Then, at the call site, the compiler will know to automatically fill in those argument values, based on the exact location where that method was called.

One great use for caller info attributes is for logging methods.  The code below defines a LogMessage method that accepts 4 parameters to output a structured log message.  However, when we call LogMessage within ProcessItem, we only need to specify one argument, message – the compiler will do the work for us to pass in the name of the method calling LogMessage, along with the file name and line number of that call site.  Even better, if ProcessItem moves around in the file, changes files, or is renamed, the log message will be updated automatically.

public void LogMessage(string message = "",
                       [CallerMemberName] string member = "",
                       [CallerFilePath] string file = "",
                       [CallerLineNumber] int line = 0)
{
    var s = String.Format("{1} ({2}:{3}) - {0}", message, member, file, line);
    Debug.WriteLine(s);
}

public void ProcessItem(int index) {
    LogMessage(String.Format("Processing item {0}", index));

    DoSomeWork();
}

Another benefit is when you’re implementing INotifyPropertyChanged.  Today, it’s common to write a helper method that invokes the PropertyChanged event, to which you pass the name of the property being set.  However, you must then pass that property name as a string argument within each property setter.  This adds risk when refactoring inside such classes – if you use VS to change the name of the property and all its references, you’ll have to manually update that string.

With caller info attributes, you can just call your NotifyPropertyChanged helper as below, without arguments.  The compiler will pass in the name of the property for you, which will always be up to date, even if the property is renamed:

public class Widget : INotifyPropertyChanged
{
    private string statusText;
    public string StatusText
    {
        get { return statusText; }
        set { statusText = value; NotifyPropertyChanged(); }
    }

    public void NotifyPropertyChanged([CallerMemberName] string property = null)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

Call to Action

If you’re excited to try out Metro style app development, async methods, caller info attributes and all the other performance and productivity improvements in Visual Studio 11 Beta, there’s a set of great resources available to explore:

  1. Get the bits!   The first step is to download Visual Studio 11 Beta – this page also has links to download Team Foundation Server 11 Beta and .NET Framework 4.5 Beta.  You can install Visual Studio 11 Beta on Windows 7 to get up and running quickly, or set it up on top of the Windows 8 Consumer Preview to start writing Metro style apps.
     
  2. Learn and explore!   Check out Jason's blog post on Visual Studio 11 Beta and .NET Framework 4.5 Beta, and then dig deeper into what’s new in Visual Studio 11 Beta.  To explore what’s new in Windows 8, first read the Building Windows 8 blog post announcing the Windows 8 Consumer Preview, and then browse the new Windows 8 app developer blog.
     
  3. Share your feedback!   As you build apps in Visual Studio 11 Beta, let us know what you think!  Discuss what’s working well and what could be better on the Visual Studio and Windows 8 forums, and be sure to file any bugs you find through the Visual Studio, LightSwitch, and Blend Connect sites.  Also, vote on the features you’d like to see in Visual Studio moving forward on our UserVoice site.

Most importantly, have fun with the Beta and build some awesome apps!

Alex Turner
Program Manager, VB/C# Compilers