Async and Await

0

Category :

Introducing the Keywords

Asynchronous methods look something like this:
public async Task DoSomethingAsync()
{
  // In the Real World, we would actually do something...
  // For this example, we're just going to (asynchronously) wait 100ms.
  await Task.Delay(100);
}

The “async” keyword enables the “await” keyword in that method. That’s all the async keyword does!
The beginning of an async method is executed just like any other method. That is, it runs synchronously until it hits an “await” (or throws an exception).
If “await” sees that the awaitable has not completed, then it acts asynchronously. It tells the awaitable to run the remainder of the method when it completes, and then returns from the async method.
Later on, when the awaitable completes, it will execute the remainder of the async method. If you’re awaiting a built-in awaitable (such as a task), then the remainder of the async method will execute on a “context” that was captured before the “await” returned.
I like to think of “await” as an “asynchronous wait”. That is to say, the async method pauses until the awaitable is complete (so it waits), but the actual thread is not blocked (so it’s asynchronous).

Return Types

Async methods can return Task, Task, or void. In almost all cases, you want to return Task or Task, and return void only when you have to.
If you have an async method returning Task or Task, then you can pass the result to await. With a void method, you don’t have anything to pass to await.
You have to return void when you have async event handlers.

Return Values

Async methods returning Task or void do not have a return value. Async methods returning Task must return a value of type T:
public async Task CalculateAnswer()
{
  await Task.Delay(100); // (Probably should be longer...)

  // Return a type of "int", not "Task"
  return 42;
}

Context

In the overview, I mentioned that when you await a built-in awaitable, then the awaitable will capture the current “context” and later apply it to the remainder of the async method. What exactly is that “context”?
Simple answer:
  • If you’re on a UI thread, then it’s a UI context.
  • If you’re responding to an ASP.NET request, then it’s an ASP.NET request context.
  • Otherwise, it’s usually a thread pool context.

  • // ASP.NET example
    protected async void MyButton_Click(object sender, EventArgs e)
    {
      // Since we asynchronously wait, the ASP.NET thread is not blocked by the file download.
      // This allows the thread to handle other requests while we're waiting.
      await DownloadFileAsync(...);
    
      // Since we resume on the ASP.NET context, we can access the current request.
      // We may actually be on another *thread*, but we have the same ASP.NET request context.
      Response.Write("File downloaded!");
    }
    

    This is great for event handlers, but it turns out to not be what you want for most other code (which is, really, most of the async code you’ll be writing).

    Avoiding Context

    Most of the time, you don’t need to sync back to the “main” context. Most async methods will be designed with composition in mind: they await other operations, and each one represents an asynchronous operation itself (which can be composed by others). In this case, you want to tell the awaiter to not capture the current context by calling ConfigureAwait and passing false, e.g.:
    private async Task DownloadFileAsync(string fileName)
    {
      // Use HttpClient or whatever to download the file contents.
      var fileContents = await DownloadFileContentsAsync(fileName).ConfigureAwait(false);
    
      // Note that because of the ConfigureAwait(false), we are not on the original context here.
      // Instead, we're running on the thread pool.
    
      // Write the file contents out to a disk file.
      await WriteToDiskAsync(fileName, fileContents).ConfigureAwait(false);
    
      // The second call to ConfigureAwait(false) is not *required*, but it is Good Practice.
    }
    
    // WinForms example (it works exactly the same for WPF).
    private async void DownloadFileButton_Click(object sender, EventArgs e)
    {
      // Since we asynchronously wait, the UI thread is not blocked by the file download.
      await DownloadFileAsync(fileNameTextBox.Text);
    
      // Since we resume on the UI context, we can directly access UI elements.
      resultTextBox.Text = "File downloaded!";
    }
    

    The important thing to note with this example is that each “level” of async method calls has its own context. DownloadFileButton_Click started in the UI context, and called DownloadFileAsync. DownloadFileAsync also started in the UI context, but then stepped out of its context by calling ConfigureAwait(false). The rest of DownloadFileAsync runs in the thread pool context. However, when DownloadFileAsync completes and DownloadFileButton_Click resumes, it does resume in the UI context.

    A good rule of thumb is to use ConfigureAwait(false) unless you know you do need the context.

    Async Composition

    So far, we’ve only considered serial composition: an async method waits for one operation at a time. It’s also possible to start several operations and await for one (or all) of them to complete. You can do this by starting the operations but not awaiting them until later:

    public async Task DoOperationsConcurrentlyAsync()
    {
      Task[] tasks = new Task[3];
      tasks[0] = DoOperation0Async();
      tasks[1] = DoOperation1Async();
      tasks[2] = DoOperation2Async();
    
      // At this point, all three tasks are running at the same time.
    
      // Now, we await them all.
      await Task.WhenAll(tasks);
    }
    
    public async Task GetFirstToRespondAsync()
    {
      // Call two web services; take the first response.
      Task[] tasks = new[] { WebService1Async(), WebService2Async() };
    
      // Await for the first one to respond.
      Task firstTask = await Task.WhenAny(tasks);
    
      // Return the result.
      return await firstTask;
    }
    

    By using concurrent composition (Task.WhenAll or Task.WhenAny), you can perform simple concurrent operations. You can also use these methods along with Task.Run to do simple parallel computation. However, this is not a substitute for the Task Parallel Library - any advanced CPU-intensive parallel operations should be done with the TPL.

    Guidelines

    Read the Task-based Asynchronous Pattern (TAP) document. It is extremely well-written, and includes guidance on API design and the proper use of async/await (including cancellation and progress reporting).
    There are many new await-friendly techniques that should be used instead of the old blocking techniques. If you have any of these Old examples in your new async code, you’re Doing It Wrong(TM):
    Old New Description
    task.Wait await task Wait/await for a task to complete
    task.Result await task Get the result of a completed task
    Task.WaitAny await Task.WhenAny Wait/await for one of a collection of tasks to complete
    Task.WaitAll await Task.WhenAll Wait/await for every one of a collection of tasks to complete
    Thread.Sleep await Task.Delay Wait/await for a period of time
    Task constructor Task.Run or TaskFactory.StartNew Create a code-based task


    Next Steps

    I have published an MSDN article Best Practices in Asynchronous Programming, which further explains the “avoid async void”, “async all the way” and “configure context” guidelines.
    The official MSDN documentation is quite good; they include an online version of the Task-based Asynchronous Pattern document which is excellent, covering the designs of asynchronous methods.
    The async team has published an async/await FAQ that is a great place to continue learning about async. They have pointers to the best blog posts and videos on there. Also, pretty much any blog post by Stephen Toub is instructive!

    my thanks to: http://blog.stephencleary.com/2012/02/async-and-await.html
    series about async and OOP programming

    Observer Pattern in .NET

    0

    Category :

    a.k.a. Publisher-Subscriber Pattern.

    Before .NET 4.0, we had to write custom code to implement Observer Pattern or use delegates and events. With the release of framework 4.0 came the IObservable and IObserver interfaces for implementing Observer Pattern.

    Background

    The Observer Pattern defines a one-to-many dependency between objects (Publisher and multiple Subscribers) so that when one object (Publisher) changes state, all the dependents (Subscriber) are notified and updated automatically.

    Sample Scenario

    The Code below is based on a scenario wherein we have a weather station which records weather data (temperature, humidity and pressure).

    This data has to be consumed by multiple displays and displayed acordingly. Everytime there is new data available to the weather station it should "push" the data to the displays which should all be updated accordingly. Suppose we have 3 displays (Current Conditions, Statistics Display and Forecast Display), all of these have to be updated whenever new data is available at the Weather Station.

    Technique #1 - Using Pure Object Oriented (OO) programming concepts.

    Publisher
    Weather Data Provider which provides the weather data, WeatherDataProvider Class implements the IPublisher interface as shown below:
    public interface IPublisher
    {
    	// Registers a new subscriber on the list of subscribers it has to 
        // notify whenever WeatherData has changed
        void RegisterSubscriber(ISubscriber subscriber);
    
        // Removes a registered subscriber from the publisher's notification list
        void RemoveSubscriber(ISubscriber subscriber);
    
        // This method actually invokes a method on the subscriber object to
        // notify that some new WeatherData is available
        void NotifySubscribers();
    }
    
    The concrete implementaion of a WeatherDataProvider would be as below:
    public class WeatherDataProvider : IPublisher
    {
        List ListOfSubscribers;
        WeatherData data;
        public WeatherDataProvider()
        {
            ListOfSubscribers = new List();
        }
        public void RegisterSubscriber(ISubscriber subscriber)
        {
            ListOfSubscribers.Add(subscriber);
        }
    
        public void RemoveSubscriber(ISubscriber subscriber)
        {
            ListOfSubscribers.Remove(subscriber);
        }
    
        public void NotifySubscribers()
        {
            foreach (var sub in ListOfSubscribers)
            {
                sub.Update(data);
            }
        }
    
        private void MeasurementsChanged()
        {
            NotifySubscribers();
        }
        public void SetMeasurements(float temp, float humid, float pres)
        {
            data = new WeatherData(temp, humid, pres);           
            MeasurementsChanged();
        }
    }
    

    Subscriber

    The subscribers here are actually the weather displays, which consume the data. Each subcsriber should implement the ISubscriber interface.
    public interface ISubscriber
    {
        void Update(WeatherData data);
    }
    
    An implementation of the CurrentConditionsDisplay is as under.
    public class CurrentConditionsDisplay : ISubscriber
    {
        WeatherData data;
        IPublisher weatherData;
    
        public CurrentConditionsDisplay(IPublisher weatherDataProvider)
        {
            weatherData = weatherDataProvider;
            weatherData.RegisterSubscriber(this);
        }
    
        public void Display()
        {
            Console.WriteLine("Current Conditions : Temp = {0}Deg | Humidity = {1}% | Pressure = {2}bar", data.Temperature, data.Humidity, data.Pressure);
        }
       
        public void Update(WeatherData data)
        {
            this.data = data;
            Display();
        }
    }
    
    Above we have injected the IPublisher interface via the Constructor.
    When the display in instantiated it makes a call to the RegisterSubscriber method of the WeatherDataProvider and registers itself as an interested subscriber.
    If a display wants to unregister itself, it has to call the RemoveSubscriber method of the WeatherDataProvider.

    Technique #3 - Using IObservable and IObserver.

    In the generic Type IObservable and IObserver, the T in our case would be WeatherData.

    Publisher

    The publisher (WeatherDataProvider) has to just implement the IObservable interface (below).
    public class WeatherDataProvider : IObservable
        {
            List> observers;
    
            public WeatherDataProvider()
            {
                observers = new List>();
            }
    
            public IDisposable Subscribe(IObserver observer)
            {
                if (!observers.Contains(observer))
                {
                    observers.Add(observer);
                }
                return new UnSubscriber(observers, observer);
            }
    
            private class UnSubscriber : IDisposable
            {
                private List> lstObservers;
                private IObserver observer;
    
                public UnSubscriber(List> ObserversCollection, IObserver observer)
                {
                    this.lstObservers = ObserversCollection;
                    this.observer = observer;
                }
    
                public void Dispose()
                {
                    if (this.observer != null)
                    {
                        lstObservers.Remove(this.observer);
                    }
                }
            }
    
            private void MeasurementsChanged(float temp, float humid, float pres)
            {
                foreach (var obs in observers)
                {
                    obs.OnNext(new WeatherData(temp, humid, pres));
                }
            }
    
            public void SetMeasurements(float temp, float humid, float pres)
            {
                MeasurementsChanged(temp, humid, pres);
            }
        }
    
    Observers register to receive notifications by calling its IObservable.Subscribe method, which assigns a reference to the observer object to a private generic List object. The method returns an Unsubscriber object, which is an IDisposable implementation that enables observers to stop receiving notifications. The Unsubscriber class is simple a nested class that implements IDisposable and also keeps a list of Subscribed users and is used by the observers (Displays in our case), to unsubscribe.

    Also, there is a function OnNext which we have invoked on the subscriber/observer. This function is actually an inbuilt function of IObserver which indicates that something has changed in the collection. This is actually the function which notifies the subscribers of changes.

    Subscriber

    The subscriber (Displays) have to just implement the IObserver interface. The implementation of the CurrentConditionsDisplay is as under. We can have similarly any number of displays.
    public class CurrentConditionsDisplay : IObserver
    {
        WeatherData data;
        private IDisposable unsubscriber;
    
        public CurrentConditionsDisplay()
        {
    
        }
        public CurrentConditionsDisplay(IObservable provider)
        {
            unsubscriber = provider.Subscribe(this);
        }
        public void Display()
        {
            Console.WriteLine("Current Conditions : Temp = {0}Deg | 
                                Humidity = {1}% | Pressure = {2}bar", 
                                data.Temperature, data.Humidity, data.Pressure);
        }
    
        public void Subscribe(IObservable provider)
        {
            if (unsubscriber == null)
            {
                unsubscriber = provider.Subscribe(this);
            }
        }
    
        public void Unsubscribe()
        {
            unsubscriber.Dispose();
        }
    
        // Pass the observer a T object that has current data, changed data, or fresh data.
        public void OnNext(WeatherData value)
        {
            this.data = value;
            Display();
        }
    
        // Notify the observer that some error condition has occurred
        public void OnError(Exception error)
        {
            Console.WriteLine("Some error has occurred..");
        }
    
        // Notify the observer that it has finished sending notifications
        public void OnCompleted()
        {
            Console.WriteLine("Additional temperature data will not be transmitted.");
        }
    }
    

    my thanks to:
    http://www.codeproject.com/Articles/796075/Implement-Observer-Pattern-in-NET-techniques