using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        
        static void Main(string[] args)
        {
            CallWithAsync();
            Console.WriteLine("Press any key to quit.");
            Console.ReadKey();
          
        }

        // common method
        private static string GetData(string actionName)
        {
            // Do your heavy work here. E.g. fetch data from a database.
            Thread.Sleep(3000);
            return string.Format("Action {0} finished. The time is {1}.", actionName, DateTime.Now.TimeOfDay);
        }
       


        // WRAPPER for async methods: these will make "GetData" asynchronous.

        private static Task<string> GetDataAsync(string name){
            // wrap the GetData method in a Task:
            return Task.Run<string>(() =>
            {
                return GetData(name);
            });

        }

        private async static void CallWithAsync()
        {
            // Call the async method and wait for its result
            string result = await GetDataAsync("Custom Action Name");
            Console.WriteLine(result);
            
        }
    }
}

The .NET framework makes multi-threading as easy as opening a can of peanut butter. Let’s make a small project to demonstrate.

Create a new C# WPF project in Visual Studio, and name it anything you like.

Drag a label and textbox on the mainwindow. Name the label “lblTime”.

Your XAML should looke something like below:


<Window x:Class="Butter.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Label x:Name="lblTime" Content="Label" HorizontalAlignment="Center" Margin="10,10,0,0" VerticalAlignment="Top"  Width="497"/>
        <TextBox x:Name="txtText" HorizontalAlignment="Left" Height="232" Margin="15,77,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="492"/>
    </Grid>
</Window>

Enter the following code in MainWindow.xaml.cs:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Butter
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            
            getTime();
        }
   
        private async void getTime(){
            
            Task task = Task.Run<string>(() => {

                System.Threading.Thread.Sleep(1000);
                return DateTime.Now.ToString();

            });

            lblTime.Content = await task;
            getTime();

        }
    }
}

Run the program. What happens? The time is displayed and updated every second. In the meanwhile you can type text in the textbox without being disturbed.

By making the method getTime async, it runs in another thread than the User Interface. Let’s analyse what’s happening in that method.

An async method needs a Task. We make one that returns a string. We invoke it with a lambda (the ()=>{} thing).

The task sleeps for a second and returns the current time.

Next, we tell the content property of the label to await the task.

What happens there? Well, the code in this method stops. Anything after the await will not be executed until the task is ready and returns a value.

In the meanwhile your program continues working. You achieved that by making the method async.

When ready, the task returns a string. The label content has been waiting for that string, and only when that string is received by the label, the rest of the code in the method is executed.

And te rest of the code… invokes the method again.