C H A P T E R  5

Image

Language

One of the dominant themes throughout this release of .NET is the ability to perform work in an asynchronous manner. Each release of .NET has given us new (and easier) ways to write async code such as the Asynchronous Programming Model (APM) and the Task Asynchronous Pattern (TAP) in C# 4.0. In the latest release, a new model using the new keywords async and await is introduced. Although this book is C# focused we will also briefly cover the new changes in VB.NET.

What Does It Mean to Do Something Asynchronously?

Let’s take a real-world example that illustrates some of the advantages and disadvantages of performing work asynchronously. A real-world frustration we all face occasionally is calling a company that leaves us on hold for a very long time—tax departments and telecom organizations are, of course, notorious for doing this. Let’s imagine we have a query about our taxes and need to call up the taxation department. We call up the department and we are automatically put on hold. You could think of this situation as being similar to a program operating synchronously so that until our call is answered, we are prevented from doing anything else.

Of course, in this scenario what most of us tend to do is then put the call on speaker phone and do something else, like find cat videos on YouTube. This could be compared to implementing multithreading in an application as it involves a context switch to see if the call has been answered yet.

Let’s imagine, however, that instead of making you wait, these companies have a new system that will automatically call you back if they are busy at the time of your call (some organizations already do this). With this facility, you are free to go and do other tasks without having to monitor the phone call with the knowledge that a representative from the company will call you as soon as one is available. This could be seen as similar to performing a task asynchronously.

Why Do Something Asynchronously?

There are a few main reasons why you would want to run code asynchronously in your applications:

  • To keep your application responsive while waiting for something that is likely to take a long time to complete
  • To make your application as scalable as possible (particularly important for services and ASP.NET that have limited threads/resources to service requests)
  • To ensure growth in cloud applications/storage and latency, which makes performing actions asynchronously more important

However, not all problems are suited to be run asynchronously through. As a rough guide, consider using async functionality in the following situations:

  • You are waiting for a response from a remote service.
  • The task you want to perform is computationally expensive and doesn’t complete very quickly (otherwise the overhead may exceed any benefits).

Can’t We Currently Do This Kind of Thing?

.NET already contains functionality to run code in an asynchronous manner, but the 4.5 features have the following advantages:

  • Less complicated code—it’s all wrapped up in one method
  • Much tidier because the callee method is responsible for handling its work rather than the method calling it
  • Easier exception handling
  • More defined methods (via interfaces) of handling cancellation and reporting on progress

Handling complications regarding thread synchronization contexts. OK, enough theory—let’s take a look at how this is done.

Async and Await

C# 5.0 introduces two new keywords—async and await—for running a method asynchronously. Let’s look at a simple example of using these now. Open up Visual Studio 2012, create a new Console application, and enter the following code:

public class Program
{
  static void Main(string[] args)
  {
    DoWorkAsync();
    //I get called immediately & before PretendToDoSomething is completed
    Console.WriteLine("Main method is all done");
    Console.ReadKey();
  }

  static async void DoWorkAsync()
  {
    await Task.Run(() => PretendToDoSomethingAsync());
    Console.WriteLine("Once PretendToDoSomething is run I will be printed");
  }

  static void PretendToDoSomethingAsync()
  {
    System.Threading.Thread.Sleep(2000);
    Console.WriteLine("I have finished pretending to do something");
  }
}

The screenshot in Figure 5-1 shows the output of running this program.

Image

Figure 5-1. Output of listing above

Let’s summarize what happened:

  1. The DoWorkAsync method was called.
  2. DoWorkAsync created a new task called PretendToDoSomethingAsync. As this is marked with the await keyword, control flow returned immediately to the main thread until this method was completed.
  3. “Main method is all done” was output.
  4. Once the Thread.Sleep was completed, then PretendToDoSomethingAsync output “I have finished pretending to do something”.
  5. Control then resumed to DoWork method that could print out “Once PretendToDoSomething is run I will also be printed”.

We could actually do something very similar in C# 4.0 as follows:

static void Main(string[] args)
{
  Task.Run(() =>
  {
    System.Threading.Thread.Sleep(2000);
    Console.WriteLine("I have finished pretending to do something");
  }).ContinueWith((result) =>
    {
      Console.WriteLine("Once PretendToDoSomething is run I will be printed");
    });
  //I get called immediatly & before PretendToDoSomething is completed
  Console.WriteLine("Main method is all done");
  Console.ReadKey();
}

So, what is the await keyword doing? The await keyword stops the async method that was called until the awaited method is completed. In the meantime, the control flow goes back to the code that first called the method.

This example isn’t too useful and could be easily accomplished with current functionality, but let’s say we wanted to perform several items of work within a loop (for example, calling several services); the new keywords make this trivial to do:

static async void DoWorkAsync()
{
  for (int i = 0; i < 5; i++)
  {
    await Task.Run(() => PretendToDoSomethingAsync());
    Console.WriteLine("End of iteration " + i);
  }
}

Async Rules

There are a couple of rules and conventions you should be aware of when using the Async functionality:

  • The compiler will give you a warning for methods that contain async modifier but no await operator.
  • A method that isn’t using the await operator will be run synchronously.
  • Microsoft suggests a convention of post-fixing an Async method with the words Async e.g. DoSomethingAsync, which seems sensible.

Async methods can return any of the following:

  • void (note an Async method that returns void cannot itself be awaited)
  • Task
  • Task<T>

Changes to BCL Methods

A number of BCL methods now have an Async version for you to use with the await keyword (see Chapter 3 for more information). The following example demonstrates the WebClient downloading the content of a web page using one of these new async methods:

class Program
{
 static void Main(string[] args)
 {
 DoWork();
 }

 static async void DoWork()
 {
 string url = “http://www.microsoft.com”;
 string content = await new WebClient().DownloadStringTaskAsync(url);
 }
}

Handling Errors

One of the language team’s goals when developing the async functionality was to make it easy to integrate into existing code. One of the aspects of this is, of course, exception handling. In the next piece of code, we have two synchronous methods: PrintMessage, which in turn calls ProcessMessage. ProcessMessage will throw an exception if the value passed to it is null or empty, so in PrintMessage the call is wrapped in a try/catch block.

class Program
{
  static void Main(string[] args)
  {
    PrintMessage("");
    Console.WriteLine("Waiting...");
    Console.ReadKey();
  }

  private static void PrintMessage(string name)
  {
    try
    {
      var result = ProcessMessage(name);
      Console.WriteLine(result);
    }
    catch (ArgumentNullException ane)
    {
      Console.WriteLine(ane.Message);
    }
  }

  private static string ProcessMessage(string name)
  {
    Thread.Sleep(1000);
    if (string.IsNullOrEmpty(name))
    {
      throw new ArgumentNullException("name", "name must have a valid value.");
    }

    return string.Format("Hi there {0}", name);
  }
}

If you run this code, the exception, as would be expected, gets caught and handled.

Now let’s change these two methods to be asynchronous (if you are trying this out, don’t forget to change the method being called in Main to PrintMessageAsync).

private static async Task PrintMessageAsync(string name)
{
  try
  {
    var result = await ProcessMessageAsync(name);
    Console.WriteLine(result);
  }
  catch (Exception ex)
  {
    Console.WriteLine(ex.Message);
  }
}

private static async Task<string> ProcessMessageAsync(string name)
{
  await Task.Delay(1000);
  if (string.IsNullOrEmpty(name))
  {
    throw new ArgumentNullException("name", "name must have a valid value.");
  }

  return string.Format("Hi there {0}", name);
}

As you can see, with the exception of adding the async and await keywords, we haven’t had to change anything in the PrintMessage method. If you run the code, the exception is caught and handled exactly as it was in the synchronous version.

Under the covers, what is actually happening to facilitate changing methods from synchronous to asynchronous is that the first exception in the Task’s AggregateException is thrown. In most cases, this behavior is acceptable, but there are instances where another approach will be necessary.

Take, for example, the following code where in the DoSomething method we await another two methods, both of which will throw exceptions (if you want to try this, just create a WPF project and add a button to the form):

private async void Button_Click_1(object sender, RoutedEventArgs e)
{
  try
  {
    var result = await DoSomething();
    MessageBox.Show(result);
  }
  catch (Exception ex)
  {
    MessageBox.Show(ex.Message);
  }
}

private async Task<string> DoSomething()
{
  var task1 = Action1Async(true);
  var task2 = Action2Async(true);
  var result = await Task<string[]>.WhenAll(task1, task2);
  return string.Join(" ", result);
}

private async Task<string> Action1Async(bool throwException = false)
{
  await Task.Delay(2000);
  if (throwException)
  throw new IOException();
  return "action 1 completed";
}

private async Task<string> Action2Async(bool throwException = false)
{
  await Task.Delay(2000);
  if (throwException)
  throw new ArgumentNullException();
  return "Action 2 completed";
}

Even though both Action1Async and Action2Async threw exceptions, the only one that gets reported is the IOException thrown by the first method. As you can imagine, this could result in some interesting side effects in your code and become problematic when debugging. One solution is to modify the DoSomething method to use ContinueWith and an instance of TaskCompletionSource to pass back the AggregationException to the calling method.

private Task<string> DoSomething()
{
  var task1 = Action1Async(true);
  var task2 = Action2Async(true);
  var tcs = new TaskCompletionSource<string>();
  Task<string[]>.WhenAll(task1, task2)
    .ContinueWith(tsk =>
    {
      if (tsk.IsFaulted)
      {
        tcs.SetException(tsk.Exception);
      }
      else
      {
        tcs.SetResult(string.Join(" ", tsk.Result));
      }
    });

  return tcs.Task;
}

Cancelling Async Methods

Something you need to consider when writing async methods, especially long-running ones, is providing a way to cancel and bail out of the process. This is easily done by modifying or providing an overload of your method to take a CancellationToken as a parameter. Within your method, you would then query the token’s IsCancellationRequested property to see if a cancellation has been requested and if it has do any clean up that is necessary and either exit the method or call the token’s ThrowIfCancellationRequested method.

The following trivial example illustrates a possible implementation:

class UsingCancellationTokens
{
  public async static void Run()
  {
    var cts = new CancellationTokenSource(3000);
    await LongRunningProcess(1000, cts.Token).ContinueWith(tsk =>
      {
        if (tsk.IsCanceled)
          Console.WriteLine("Process cancelled");
        else
          Console.WriteLine("Process completed");
      });
  }

  private async static Task LongRunningProcess(int counter, CancellationToken token)
  {
    for (int i = 0; i < counter; i++)
    {
      await Task.Delay(100);
      if (token.IsCancellationRequested)
      {
        token.ThrowIfCancellationRequested();
      }
      Console.WriteLine(i);
    }
  }
}

Async/Await under the Hood

Given the relative simplicity of implementing asynchronous methods using the async/await keywords, clearly there is more going on than meets the eye. Before we look at what is happening under the covers, let’s first review what is actually happening when we use the async and await keywords.

When you call an async method, it runs until it encounters an awaitable method (that is, a method marked with await). At that point, it returns to the calling code and then happily continues running. Once the awaited method completes, however, any other code in the async method is then processed.

But how is the compiler achieving this magic?

Behind the scenes, the compiler is generating code for managing the state of your method and intercepting calls to it. When a method is tagged with the async keyword, the compiler creates a helper state machine for the method. A stub method is created with a signature corresponding to the original method but with a shiny new implementation containing code for setting up the state machine and initiating it with a call to its MoveNext method.

The state machine then maintains what’s going on across asynchronous await points. Within it, if required, it will contain the method’s original code but segmented to allow results and exceptions to pass into the returned Task and facilitate continuation after an await.

Phew, that is a lot to take in!

Image Note Stephen Toub, in his MSDN article on Async performance (http://msdn.microsoft.com/en-us/magazine/hh456402.aspx), said that when you start working with asynchronous methods, “a new mental model is needed.”

Implementing async/await By Hand

At this point, we would crack open our preferred IL decompiler and look at how the compiler rewrites an async method. Instead, taking inspiration from Mads Torgersen’s article “Pause and Play with Await” (http://msdn.microsoft.com/en-us/magazine/hh456403.aspx), we are going to hand roll our own state machine to mimic async/await functionality and understand what’s really going on here.

First, here is the method we are going to make asynchronous:

public void GetHtml(string url)
{
  var webClient = new WebClient();
  try
  {
    var result = webClient.DownloadString(url);
    Console.WriteLine(result);
  }
  catch (WebException webEx)
  {
    Console.WriteLine(webEx.Message);
  }
  finally
  {
    webClient.Dispose();
  }
}
  1. To get started, create a new console application project.
  2. Once you have that up, add a new class and call it Example, open it, and add using statements for the following namespaces:
    •     System.Diagnostics
    •     System.Net
    •     System.Runtime.CompilerServices
    •     System.Threading
    •     System.Threading.Tasks
  3. Within the Example class, you are going to add a nested type to act as our state machine. The following code defines your state machine:
    private struct GetHtmlAsyncStateMachine
    {
      public int state;
      public AsyncTaskMethodBuilder builder;
      public string result;
      private WebClient webClient;
      public string url;
      private TaskAwaiter<string> awaiter;

      public void MoveNext()
      {
        try
        {
          if (state == 1)
          goto doStuff;

          webClient = new WebClient();
          doStuff:
          try
          {
            if (state == 1)
              goto completed;
            awaiter = webClient.DownloadStringTaskAsync(url).GetAwaiter();
            if (!awaiter.IsCompleted)
            {
            state = 1;
            //Specify this method as the continuation action
            //for when the await action completes
            awaiter.OnCompleted(this.MoveNext);
            return;
            }
            completed:
            result = awaiter.GetResult();
            //continue processing at this point
            Console.WriteLine(result);

          }
          catch (WebException webEx)
          {
            Console.WriteLine(webEx.Message);
          }
        }
        catch (Exception ex)
        {
          state = 2;
          builder.SetException(ex);
          return;
        }
        finally
        {
          webClient.Dispose();
        }
      state = 2;
      builder.SetResult();
      }
    }
  4. Next, you will modify your original method to function in an async manner by instantiating the state machine and then kick it off by calling its MoveNext method. Add the next piece of code to the Example class:
    public Task GetHtmlAsync(string url)
    {
      var stateMachine = new GetHtmlAsyncStateMachine();
      stateMachine.builder = AsyncTaskMethodBuilder.Create();
      stateMachine.url = url;
      stateMachine.MoveNext();
      return stateMachine.builder.Task;
    }
  5. Finally, to see this all working, open Program.cs and in the Main method add the following:
    var example = new Example();
    example.GetHtmlAsync("http://www.microsoft.com");
    Console.WriteLine("Waiting ...");
    Console.ReadKey();

With this example what we have done, in a simplified form, is essentially what the compiler does when you use the async/await keywords on a method. So, for example, if we take our original synchronous and modify it to be asynchronous like so:

public async Task GetHtmlAsync(string url)
{
var webClient = new WebClient();
  try
  {
    var result = await webClient.DownloadStringTaskAsync(url);
    Console.WriteLine(result);
  }
  catch (WebException webEx)
  {
    Console.WriteLine(webEx.Message);
  }
  finally
  {
    webClient.Dispose();
  }
}

Here is how it would look when viewed in an IL decompiler:

public class Example
{
  [DebuggerStepThrough, AsyncStateMachine(typeof(<GetHtmlAsync>d__0))]
  public Task GetHtmlAsync(string url)
  {
    <GetHtmlAsync>d__0 d__;
    d__.<>4__this = this;
    d__.url = url;
    d__.<>t__builder = AsyncTaskMethodBuilder.Create();
    d__.<>1__state = -1;
    d__.<>t__builder.Start<<GetHtmlAsync>d__0>(ref d__);
    return d__.<>t__builder.Task;
  }

  // Nested Types
  [CompilerGenerated]
  private struct <GetHtmlAsync>d__0 : IAsyncStateMachine
  {
    // Fields
    public int <>1__state;
    public Example <>4__this;
    public AsyncTaskMethodBuilder <>t__builder;
    private object <>t__stack;
    private TaskAwaiter<string> <>u__$awaiter3;
    public string <result>5__2;
    public WebClient <webClient>5__1;
    public string url;

    // Methods
    private void MoveNext()
    {
      try
      {
      bool <>t__doFinallyBodies = true;
      switch (this.<>1__state)
      {
        case -3:
          goto Label_0121;
        case 0:
          break;
        default:
          this.<webClient>5__1 = new WebClient();
          break;
      }
      try
      {
        int CS$4$0000 = this.<>1__state;
        if (CS$4$0000 == 0)
        {
        }
        try
        {
          TaskAwaiter<string> CS$0$0001;
          CS$4$0000 = this.<>1__state;
          if (CS$4$0000 != 0)
          {
            CS$0$0001 = this.<webClient>5__1.DownloadStringTaskAsync(this.url).GetAwaiter();
            if (!CS$0$0001.IsCompleted)
            {
              this.<>1__state = 0;
              this.<>u__$awaiter3 = CS$0$0001;
              this.<>t__builder.AwaitUnsafeOnCompleted<TaskAwaiter<string>,
Example.<GetHtmlAsync>d__0>(ref CS$0$0001, ref this);
              <>t__doFinallyBodies = false;
              return;
            }
          }
          else
          {
            CS$0$0001 = this.<>u__$awaiter3;
            this.<>u__$awaiter3 = new TaskAwaiter<string>();
            this.<>1__state = -1;
          }
          string result = CS$0$0001.GetResult();
          CS$0$0001 = new TaskAwaiter<string>();
          string CS$0$0003 = result;
          this.<result>5__2 = CS$0$0003;
          Console.WriteLine(this.<result>5__2);
        }
        catch (WebException webEx)
        {
          Console.WriteLine(webEx.Message);
        }
        }
        finally
        {
          if (<>t__doFinallyBodies)
          {
          this.<webClient>5__1.Dispose();
          }
        }
      }
      catch (Exception <>t__ex)
      {
        this.<>1__state = -2;
        this.<>t__builder.SetException(<>t__ex);
        return;
      }
      Label_0121:
      this.<>1__state = -2;
      this.<>t__builder.SetResult();
    }

    [DebuggerHidden]
    private void SetStateMachine(IAsyncStateMachine param0)
    {
      this.<>t__builder.SetStateMachine(param0);
    }
  }
}

True, there is a lot more going on here, but in essence it is the same as our hand-rolled version. However, instead of us having to write it, the IL compiler is doing all the heavy lifting for us.

Some Things To Think About

The ease with which the async/await keywords allows us to create asynchronous methods is beguiling, but as you can see from the previous example, there is more to it than meets the eye. This, in turn, can lead to performance issues. Stephen Toub covers these issues in depth in his article mentioned earlier, but here some key points to consider:

  • Methods should be chunky, not chatty. When working synchronously, using small, discreet methods incurs little cost when compiled. It is a different story when we switch to an asynchronous approach. For any given async method, the compiler has to, as we have seen, generate a fair amount of extra scaffolding to make a method asynchronous and that is an extra cost. So, where possible, it is worthwhile consolidating a logical piece of functionality into a single method.
  • Beware that any variables within an async method will be lifted into the state machine and this can impact on garbage collection.
  • Consolidate multiple awaits. If you have multiple awaits, consider rationalizing them into a single await by using the Task.WhenAll method.
  • Know when not to async.

Caller Information

Another new feature that has been added to both C# and VB.NET is caller information attributes. Defined in the System.Runtime.CompilerServices namespace, there are three attributes:

  • CallerFilePathAttribute, which returns the full path to the source file of the caller as of compile time
  • CallerLineNumberAttribute, which identifies the line number in the source file where the method was called
  • CallerMemberNameAttribute, which holds the name of the method or property of the caller

To use these attributes, you need to apply them to optional parameters on a method with a default value. For example:

SomeMethod(string message, [CallerFilePath] string sourceFile = "",
           [CallerLineNumber] int sourceLineNo = 0, [CallerMemberName] string memberName = "")

The attributes don’t make the parameters optional but determine the default value when the argument is omitted. Unlike the StackTrace property of an exception, they are not affected by obfuscation since they are injected as literals into the IL.

Essentially, the idea behind these attributes is to facilitate debugging, tracing, and the creation of diagnostic tools. The following example shows how this could be used:

class Program
{
static void Main(string[] args)
  {
    Trace.Listeners.Clear();
    Trace.Listeners.Add(new ConsoleTraceListener());
    var repository = new ProjectRepository();
    repository.AddProject(new ProjectModel { ProjectName = "Test Project" });
    Console.ReadKey();
  }
}

public class ProjectModel
{
  public string ProjectName { get; set; }
}

public class ProjectRepository
{
  public void AddProject(ProjectModel project,
        [CallerFilePath]string srcFilePath = "",
        [CallerLineNumber] int srcLineNo = 0,
        [CallerMemberName] string memberName = "")
  {
    Trace.WriteLine("Project Added");
    Trace.WriteLine("Member name: " + memberName);
    Trace.WriteLine("Source file path: " + srcFilePath);
    Trace.WriteLine("source line number: " + srcLineNo);
  }
}

Running this example would generate something similar to Figure 5-2.

Image

Figure 5-2. The trace output

Though useful for diagnostic purposes, using these attributes adds clutter to your method signatures, which you do need to consider if you are going to use them. Outside of the diagnostics realm, the CallerMemberNameAttribute comes into its own when implementing the INotifyPropertyChanged interface.

When implementing this interface on, say, a view model, a common practice is to create a method that takes a property name as a string literal to then raise the PropertyChanged event—for example, OnPropertyChanged("PropertyName"). This can introduce subtle bugs if the property name is changed, but the value in the method call isn’t. An alternative to this was to create a method that took an expression, OnPropertyChanged<T>(Expression<Func<T>> e), that could then be called as follows: OnPropertyChanged(() => this.PropertyName). By using the CallerMemberNameAttribute the whole thing can be simplified as seen in this code example:

public class ProjectVM : INotifyPropertyChanged
{
  public event PropertyChangedEventHandler PropertyChanged;
  private ProjectModel model;
  public string ProjectName
  {
    get { return model.ProjectName;}
    set
    {
      model.ProjectName = value;
      OnPropertyChanged();
    }
  }

  private void onPropertyChanged([CallerMemberName] string memberName = "")
  {
    if (PropertyChanged == null)
          return;
    PropertyChanged(this, new PropertyChangedEventArgs(memberName));
  }
}

VB.NET

Although we are mainly focusing on C# in this book, we want to make you aware that VB.NET has been enhanced with a number of features to bring it into line with C#.

Call Hierarchy

Call Hierarchy was introduced to C# in Visual Studio 2010 and allows you to see where various methods are being called from and what they call from the IDE. This feature is now available in VB.NET as well. (See Figure 5-3.)

Image

Figure 5-3. Call Hierarchy has now been introduced to VB.NET.

Iterators

An iterator is a type of collection object that allows a client to iterate through each object in the collection. Microsoft defines it as the following:

An iterator is a method, get accessor or operator that enables you to support foreach iteration in a class or struct without having to implement the entire IEnumerable interface. Instead, you provide just an iterator, which simply traverses the data structures in your class. When the compiler detects your iterator, it will automatically generate the Current, MoveNext and Dispose methods of the IEnumerable or IEnumerable<T> interface.

http://msdn.microsoft.com/en-us/library/dscyy5s0(v=vs.80).aspx

Iterators are particularly useful for wrapping up complex logic to transverse complex structures, for example, a hierarchical tree. When you use an iterator behind the scenes, the compiler generates a state machine (for more information, see www.abhisheksur.com/2011/01/internals-to-c-iterators.html) that tracks the current item and provides get next methods each time it is called.

Iterators were first introduced in the first release of C# and have now been introduced into VB.NET. The following example shows how to create an iterator that will return a name from a predefined list each time it is called:

Sub Main()
 For Each name As String In NamesIterator()
 Console.WriteLine(name)
 Next

 Console.ReadKey()
End Sub

Private Iterator Function NamesIterator() As System.Collections.Generic.IEnumerable(Of String)
 Dim ListOfNames As New List(Of String)
 ListOfNames.Add(“Karen”)
 ListOfNames.Add(“Trish”)
 ListOfNames.Add(“Billy”)

 For Each name In ListOfNames
 Yield name
 Next

End FunctionNamespaces

By constructing your namespaces in a specific manor, it is possible to block access to certain namespaces. For example, the following will not compile (when the error Type ‘System.Guid’ is not defined) as the use of MyNamespace.System prevents access to .NET’s System namespace:

Namespace MyNamespace
  Namespace System
    Public Class SomeClass
            Function DoSomething()
                Dim myGuid = New System.Guid
            End Function
    End Class
  End Namespace
End Namespace

If you find yourself in this situation, you probably want to refactor your namespaces. However, if you can’t for some reason or you are using third-party libraries, you can use the Global keyword to tell .NET to start at the outermost namespace (for more on Global see the next section):

Dim myGuid = New Global.System.Guid

Global and Namespace

In Visual Basic, all namespaces are based on the project’s root namespace (often the project’s name, for example, ConsoleApplication1—you can override this in project properties). The Global keyword allows you define a namespace outside of this:

Namespace Global.OutsideTheProjectNamespace
End Namespace

Or the more verbose:

Namespace Global
    Namespace OutsideTheProjectNamespace

    End Namespace
End Namespace

The Global keyword also allows you to specify namespaces that would clash with .NET’S namespace—note that this will only work if you prefix them:

Namespace MyNamespace
    Namespace System
        Public Class SomeClass
            Sub DoSomething()
                Dim obj As New Global.System.IO.AlexClass
                Dim wouldntWorkWithoutGlobal As Global.System.IO.StreamReader
            End Sub
        End Class
    End Namespace
End Namespace
Namespace Global.System.IO
    Class AlexClass
    End Class
End Namespace

This seems like a bad idea to me and would likely cause you more hassle than it’s worth, so I would avoid it.

Real-World Async

Jake Ginnivan, MVP VSTO http://jake.ginnivan.net/

In January 2012, we decided that we would upgrade a large WPF application (from a two-year-old project) to use the async CTP. We put a lot of effort into making sure that the application never blocked the UI thread and gave the user visual feedback when the application was busy. The application also had a suite of UI automation tests that understood when the application is doing background work so the test doesn’t continue.

This meant that our code suffered from a fair amount of lambda tax. As an example, a WCF call looked something like this:

    _uiService.CallWithBusy(
       _someService,
        service => service.ServiceCall(arg1, arg2),
        complete =>
        {
            if (DoDefaultErrorHandling(complete))
                return;
            // Update UI etc
        }

So, our main motivation for adopting the async CTP was to make our code cleaner and easier to write. Now a service call looks like the following:

Try
{
    var result = await _someServiceAsync.ServiceCall(arg1, arg2);
    // Update UI etc
}
Catch (Exception ex)
{
    ex.DoDefaultErrorHandling(_uiService);
}

These examples are simple, but often we had multiple service calls or other async tasks. It is a very common occurrence in rich clients that you need to use the result of one call to pass to another. This makes it very hard to follow the logic and flow of the code. There were places in the code base where we reduced 100 lines of code to about 30 just by using the async/await keywords. After using these language features, it makes it very hard to go back!

For us, async/await is like LINQ—we really struggle to go back and do it the old way. We are also now adopting ASP.NET Web API and making use of the support for Asynchronous Controller actions, allowing us to get much greater throughput on our central server. This is what makes the async stuff so great—it can help you write fast asynchronous code, but even if you don’t need the additional throughput, the async language features in .NET 4.5 can help you write cleaner code as well.

Conclusion

The async and await keywords will make it much easier and intuitive to integrate Asynchronous functionality into your applications. It is probably a sign of the maturity of both C# and VB.NET that the only other new feature in this release has been the introduction of Caller Info attributes.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.151.220