C# Asynchronous Programming

Modern C# is a first class language to support asynchronous pattern. Its async/await, related keywords and Task Parallel Library enable us to comfortably utilize async features.

Basics

Task Parallel Library is a higher level abstraction of previous threading library. Instead of creating Thread to do some work we create Task instead. To create and run a new thread comfortably using a lambda expression, we can use Task.Run. Example,

var resultStr = Task.Run(() => MyFoo()).Result;

Task.Delay is an async sleep method that we use every now and then to simulate some async work.

Demonstrating Examples

All these example codes are available at github/atiq-cs/cs-async-demos.

First example demonstrates how to run create and run a thread synchronously.. The program does not even wait for the thread to complete. Hence, all output from the new thread might not be displayed.

// example 1
static void Main(string[] args) {
  ThreadingTest demo = new ThreadingTest();
  Console.WriteLine("Before running my foo()");
  demo.Run();
  Console.WriteLine("After running my foo()");
}

Second example, does not create any new thread.

// example 2
static void Main(string[] args) {
  ThreadingTest demo = new ThreadingTest();
  Console.WriteLine("Before running my foo()");
  demo.Run();
  Console.WriteLine("After running my foo()");
  Task.Delay(2000);
}

However, it marks its method as async. Additionally, it includes a potential beginner’s mistake: marking method as async void.
Task.Delay in main method has has no effect. It would return almost instantly since, await keyword is not used with the async method. Task.Delay does not create a new thread.
It is upto the reader to guess what the output is!

3rd example, mixes sync and async methods. New thread method is sync and it using Task.Delay does not make any sense.

static void Main(string[] args) {
  ThreadingTest demo = new ThreadingTest();
  Console.WriteLine("Before running my foo()");
  demo.Run();
  Console.WriteLine("After running my foo()");
}

By calling an async method from a sync method we are mixing up. Recommendation is to,

  • await an async method
  • since using await requires a method to be async as well, declare it as async

Best practices,

  • not to mix async methods with sync methods
  • not retrieving results using Task.Result, instead use await
  • do not use async void instead of async Task for methods that return nothing

Example 3 is better. However, it exemplifies Task.Delay without await.

Example 4 fixes all those flaws and additionally uses an async main method.
We use latest C# language which allows us to make main method to be async. We add following line to include C# lang version support of 7 or later,

<LangVersion>7.3</LangVersion>

Or,

<LangVersion>Latest</LangVersion>

inside the .csproj file.

// example 4
class p4AsyncMain {
  static async Task Main(string[] args) {
    ThreadingTest demo = new ThreadingTest();
    await demo.Run();
    Console.WriteLine("Main terminates");
  }
}

Program 5 shows how the async method is blocking main thread. Since async method is running on the caller thread it is blocked and it cannot do anything till the method returns. If we want to do work concurrently in both the main method and the additional async method we have to call the addition method (represent work) creating a new thread i.e., using Task.Run.

Example 6, creates a new thread for the represented work (a timer). While new thread is performing timer work main thread performs calculation of fibonacci numbers.

  class p6TimerAsyncNonblocking {
    static async Task Main(string[] args) {
      Timer tDemo = new Timer();
      Task timerToFinish = Task.Run(() => tDemo.Run());
      // at this point, runs fibo and timer concurrently
      MathCompute mathWork = new MathCompute();
      mathWork.fibo();
      // now let's wait till timer finishes
      await timerToFinish;
      // assuming we might need some result from timerToFinish from here, otherwise we can do more
      // work and then 'await'
      Console.WriteLine("main terminates");
    }
  }

Example codes used above are available at github/atiq-cs/cs-async-demos.

When to use ConfigureAwait

Quoting Juan @ Bynder – C#: Why you should use ConfigureAwait(false) in your library code,

This changes the continuation behavior of GetJsonAsync so that it does not resume on the context. Instead, GetJsonAsync will resume on a thread pool thread. This enables GetJsonAsync to complete the Task it returned without having to re-enter the context.

As per Stephen Cleary – Don’t Block on Async Code best practices can be,

  • To use ConfigureAwait(false) in library codes

We can’t use ConfigureAwait if we need current thread’s context for example UI Thread for GUI applications.. Here is a nice example of a similar scenario Async/Await – Best Practices in Asynchronous Programming.

However, when we are calling async methods in .net core web applications any thread from the threadpool would suffice, we don’t need resume context of current thread. Hence, ConfigureAwait(false) is perfect application in such cases.

More related resources

.net basic concepts

As of now, we have 3 versions of .net implementations,

  • .net core
  • .net standard
  • .net framework

.net core is new open-source, cross-platform implementation of .net API where .net framework is the old one; it is the largest implementation which has UI, WPF. Xamarin also implements .Net. All of these implementations have Base Class Library. These Base Class Libraries require some sort of contract for better compatibility and inter-operability. That’s where .net standard come into play.

.net standard is the standard that all .net implementations should follow.

Higher the .net standard version, bigger the API is. For example, if we are targeting .net standard 2.0 we have access to System.Data namespace. If lower the target version it becomes 1.0. Consider a solution that have a number of projects, if a project is targeting .net standard 2.0 and another project is using that project. That project cannot target an equivalent .net framework that is less in target .net standard version. youtube video – Understanding .NET Standard, .NET Core and .NET Framework. Earlier .net standard supported some old devices which new versions don’t support them.

Quoting stackoverflow – What is the difference between .NET Core and .NET Standard Class Library project types?

Ignoring libraries for a moment, the reason that .NET Standard exists is for portability; it defines a set of APIs that .NET platforms agree to implement. Any platform that implements a .NET Standard is compatible with libraries that target that .NET Standard. One of those compatible platforms is .NET Core.

References

Windows 10 Update Enable Playing Videos with x265 Encoding

On my new notebook, Dell XPS 15 9560, I first saw this problem. When I try to play an x265 video file using Windows 10 Movies and TV Player, it will only play the audio in background and show an error dialog box instead of rendering the video,

codec missing 0xc00d5212

I dug a little bit and I found that this is a problem starting Windows 10 Fall Creators Update. Since I did a Fresh installation of Windows 10 I encountered this.

Which means this is not a problem with Hardware of notebooks such as Dell XPS 15 or 13, it’s rather an operating system – Windows 10.

Looks like solution is pretty simple. We need to install an extension from Microsoft: HEVC Video Extensions from Device Manufacturer. Afterwards, Windows can play all videos (mkv, mp4 etc with x265) again, no 3rd party player or codec is required.

Primary reference: winaero – Get HEVC Decoder for Windows 10 Fall Creators Update

Running Windows Server on Container Instance

For now, this article only covers Azure Cloud.

ACI is good for running single container up easily and running.

Running a Windows Server Container on Azure
https://ronaldwildenberg.com/azure/2018/01/25/running-windows-server-container-in-azure.html

az container
https://docs.microsoft.com/en-us/cli/azure/container?view=azure-cli-latest#az-container-deletexrr

Execute a command in a running Azure container instance

https://docs.microsoft.com/en-us/azure/container-instances/container-instances-exec

Azure CLI Basics

Introduction

A strong CLI is useful to manage cloud resources easily. It helps automation, scripting and logging. It is handy in managing basic docker (Azure Container Services) stuff as well.

If you are new to Azure CLI it helps a lot took at the MS Docs – Getting Started documentation page. Documentation root is at MS Docs – Azure CLI 2.0

Here are few ways to access Azure Resources,

  • Azure Portal
  • Azure Powershell
  • SDKs – fluent .net api, supports other languages,
  • service principal (can be used to created using CLI)
  • REST API {JSON}

Here is the work flow for azure-cli.

  • First, we login to azure using CLI.
  • Second, we create/delete/modify resources.
  • Third, We perform actions on resource.

Additionally, I usually set the path manually in a command prompt,

C:> set PATH=%PATH%;C:\Program Files (x86)\Microsoft SDKs\Azure\CLI2\wbin

On a powershell, if you ever need to add this manually to path var,

$ $Env:Path += 'C:\Program Files (x86)\Microsoft SDKs\Azure\CLI2\wbin;'

Azure CLI is a cross-platform tool built using python, Wix. az commands in this article should work across all operating systems.

To check what version is installed,

$ az --version
azure-cli (2.0.43)
... .... ....

Python location 'C:\Program Files (x86)\Microsoft SDKs\Azure\CLI2\python.exe'
Extensions directory 'C:\Users\Neo\.azure\cliextensions'
Python (Windows) 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 16:07:46) [MSC v.1900 32 bit (Intel)]
Legal docs and information: aka.ms/AzureCliLegal

To access interactive version of Azure CLI, we enter an interactive session,

az interactive

Finally, here’s a brief overview of Azure CLI.

Azure CLI Intro

We can use Azure Cloud Shell as well to access Azure-CLI. It however requires a storage account. More info at MS Docs – Overview of Azure Cloud Shell

1. Azure login

login command looks like following,

$ az login
Note, we have launched a browser for you to login. For old experience with device code, use "az login --use-device-code"
You have logged in. Now let us find all the subscriptions to which you have access...

[
  {
    "cloudName": "AzureCloud",
    "id": "c2eax898-6232-4834-8e65-5e2cbeac0919",
    "isDefault": true,
    "name": "My Pay As You Go",
    "state": "Enabled",
    "tenantId": "cde5d866-bf04-4fa4-8da1-b3282cdb843b",
    "user": {
      "name": "matrix@morphis-system.com",
      "type": "user"
    }
  }
]

It automatically opens up a new browser Windows where we login to the account. Once we are logged into the azure portal, authentication token is automatically picked up the command prompt CLI instance.
In future az commands same authentication is continued to be used.

As we can see above, in command output, after logging in, it lists available subscriptions with the with Azure Cloud account. Following command also lists subscriptions,

$ az account list

This lists all subscriptions under the account. Commands we apply work on current subscription context. To show currently set subscription context,

$ az account show

If you have more than one subscription you might want to set the active subscription globally which can be done in following way ref,

$ az account set -s "My Pay As You Go"

which is equivalent to,

$ az account set --subscription "My Pay As You Go"

More info can be found at MS Docs – Manage multiple Azure subscriptions

For login we can use service principals as well, here’s an example of logging in with service principal,

az login --service-principal -u $servicePrincipalAppId --password $spPassword --tenat $tenantId

2. Managing Resource

We can do following managing of Azure Resources,

  • Create
  • Query
  • Update
  • Delete

Here are few examples below,

list examples

To list VMs we do,

$ az vm list
[]

Currently, I do not have any VM. Hence, the empty array shows up in output.

To list resource groups we do,

$ az group list
[
  {
    "id": "/subscriptions/c2eax898-6232-4834-8e65-5e2cbeac0919/resourceGroups/asynctest",
    "location": "westus",
    "managedBy": null,
    "name": "asynctest",
    "properties": {
      "provisioningState": "Succeeded"
    },
    "tags": null
  },
  {
    "id": "/subscriptions/c2eax898-6232-4834-8e65-5e2cbeac0919/resourceGroups/blog",
    "location": "centralus",
    "managedBy": null,
    "name": "blog",
    "properties": {
      "provisioningState": "Succeeded"
    },
    "tags": null
  },
  {
    "id": "/subscriptions/c2eax898-6232-4834-8e65-5e2cbeac0919/resourceGroups/ML",
    "location": "westus2",
    "managedBy": null,
    "name": "ML",
    "properties": {
      "provisioningState": "Succeeded"
    },
    "tags": null
  },
  {
    "id": "/subscriptions/c2eax898-6232-4834-8e65-5e2cbeac0919/resourceGroups/Speech",
    "location": "westus",
    "managedBy": null,
    "name": "Speech",
    "properties": {
      "provisioningState": "Succeeded"
    },
    "tags": null
  }
]

To show available azure function apps,

az functionapp list

Following screenshot from Azure CLI course by Mark Heath shows some more examples,
Azure CLI Show Resource Example

Using Query Language JMES

To select only field: state, to check whether the app is Running or not,

az functionapp show -n func -g myfuncs --query state

We can query multiple fields such as state and ftpPublishingUrl using array like syntax,

--query "[state, ftpPublishingUrl]"

Query language used in Azure CLI is called JMESPath.

We can rename properties in output,

az funcapp list --query "[].{Name:name, Group:resourceGroup, State: state}"

It feels like similar to the C# Feature where we can dictionary like, name fields in output,

Create Examples

To create a new resource group we do,

$ az group create --name MyContainers --location westus
{
  "id": "/subscriptions/c2eax898-6232-4834-8e65-5e2cbeac0919/resourceGroups/MyContainers",
  "location": "westus",
  "managedBy": null,
  "name": "MyContainers",
  "properties": {
    "provisioningState": "Succeeded"
  },
  "tags": null
}

Navigating help

To view top level help,

az -h

To view help on sub-topic webapp,

az webapp -h

To view help sub-topic of webapp: create,

az webapp create -h

To view help sub-topic of webapp: config,

az webapp config -h

-h applies to all available sub-commands.

Managing Web App and Other Resources

Here’s a brief overview of things we can do,

Azure CLI Managing Web Apps and Resources

Listing webapps,

az webapp list

To create new resource group,

az group create -n ResourceGroupName -l westus

To view help on App service plan create command,

az appservice plan create -h

Here’s an example, how we create an webapp under specified app service plan,

az webapp create -n AppName -g ResourceGroupName --plan AppServicePlanName

To show newly created app and query its host name,

az webapp show -n AppName -g ResourceGroupName --query "defaultHostName"

We can perform webapp deployment from source control,

az webapp deployment source config -n AppName -g ResourceGroupName --repo-url GIT_REPO_URL --branch master --manual-integration

For automatic integration with github we need to pass a git token.

In summary,

Azure CLI Managing Web Apps and Resources

To trigger redeployment we do,

az webapp deployment source sync -n AppName -g ResourceGroupName

SQL Server Resources

To create new SQL Server,

az sql server create -n SqlServerName -g ResourceGroupName -l Location -u sqlServerUserName -p sqlServerPass

List what pricing tiers are availabe for SQL Database,

az sql db list-editions -l Location -o table

To show outboundIpAddresses,

az webapp show -n AppName -g ResourceGroupName --query "outboundIpAddresses" -o tsv

Brief overview of SQL Server command examples below,

SQL Server Command Examples

To create sql server firewall,

az sql server firewall-rule create -g ResourceGroupName -s SqlServerName -n AllowWebApp1 --start-ip-address 0.0.0.0 --end-ip-address 0.0.0.0

We can get the connection string using the CLI as well. Afterwards, we can set the connection string to the webapp,

az webapp config connection-string set -n AppName -g ResourceGroupName --settings \
"SnippetsContext=$connectionString" --connection-string-type SQL-Azure

Import/Export SQL Database
An export example,

 az sql db export -s $sqlServerName -n $databaseName -g $ResourceGroupName \
 -u $sqlServerUserName -p $sqlServerPass --storage-key-type StorageAccessKey \
 --storage-key $storageKey --storage-uri "StorageBlobURL"

To restore database from backup, we use a new database. As we know, we cannot restore into current database.We can only restore into blank database.
So we create new database, get the connection-string, and use this new connection-string on the webapp.

Export procedure overview,

SQL Server Export Examples

Deployment procedure overview,

Deployment using CLI

Output Formatting

By default, output is displayed in JSON format. Using -o table we can have tabular format output.

To display the output as a table we add --out table. Here’s an example,

$ az container list --out table

Azure Container Instance Related Commands

Listing containers,

$ az container list
[
  {
    "containers": [
      {
        "command": null,
        "environmentVariables": [],
        "image": "microsoft/iis:nanoserver",
        "instanceView": null,
        "livenessProbe": null,
        "name": "MyServerCoreCI",
        "ports": [
          {
            "port": 80,
            "protocol": "TCP"
          }
        ],
        "readinessProbe": null,
        "resources": {
          "limits": null,
          "requests": {
            "cpu": 1.0,
            "memoryInGb": 1.5
          }
        },
        "volumeMounts": null
      }
    ],
    "diagnostics": null,
    "id": "/subscriptions/c2eax898-6232-4834-8e65-5e2cbeac0919/resourceGroups/dockers/providers/Microsoft.ContainerInstance/containerGroups/MyServerCoreCI",
    "imageRegistryCredentials": null,
    "instanceView": null,
    "ipAddress": {
      "dnsNameLabel": null,
      "fqdn": null,
      "ip": "40.78.17.202",
      "ports": [
        {
          "port": 80,
          "protocol": "TCP"
        }
      ]
    },
    "location": "westus",
    "name": "MyServerCoreCI",
    "osType": "Windows",
    "provisioningState": "Succeeded",
    "resourceGroup": "dockers",
    "restartPolicy": "Always",
    "tags": {},
    "type": "Microsoft.ContainerInstance/containerGroups",
    "volumes": null
  }
]

Azure Resource Manager (ARM)

Azure Resource Manager, in brief ARM helps deployment procedure automated and sophisticated.
We can perform group deployment using ARM.

Then check what the newly created resourceGroup contains,

az resource list -g ResourceGroupName -o table

Create deployment overview,
SQL Server Command Examples

To get domain name property of first public ip,

az network public-ip list -g ResourceGroupName --query "[0].dnsSettings.fqdn" -o tsv

To generate template from existing from resource group we can utilize command similar to,

az group export

Sometimes, there are things in the resource group that cannot be represented in an ARM template.

Bug of current CLI turns this warning into an error.. Compared to github deployment json this is much more verbose and specific..

Another way to create ARM Template is using Visual Studio, ARM Tooling.

Recommended Courses

Misc.

Azure CLI Windows build script can be found at references section. Additionally, we can configure with Active directory,
Active Directory Examples

Reference

Windows 10 Installation – Forcing to a different edition of Windows

Here’s an example of the problem.

Say you purchased a Dell XPS Notebook which comes with pre-installed Windows 10 Core (Home Edition). Now, you might have,

  • an Enterprise Edition of Windows or License
  • a Pro Edition of Windows or License

There might be a number of reasons why you might go with a superior license which you have or you can afford,

  • Pro edition or enterprise edition has features that are not available with Home edition
  • Simple things like remote desktop connection would not work with a home edition, so may be it’s better keep the option open if you need those features in future.

The simplest way to upgrade would be to go to Windows Product Key from control panel and change the Key. Windows should install everything as required for the Pro version.

Now, you might be wondering, like the old days, we can reinstall Windows using Installation Media and during installation it would ask nicely which version (Pro or Home or Enterprise etc) we want to install. Unfortunately, that does not work for many of the new systems where Windows Setup automatically detects previously installed Windows’s version like a rude robot! It chooses that version of Windows such as Windows Home edition every time we do reinstall.

Here’s a way to force it to Pro Edition. This is easier with USB Installation Media tool. All we need to do, is put two configuration files specified the edition and the product key.

  • ei.cfg
  • pid.txt

Sample ei.cfg for Pro edition looks like,

[EditionID]
Professional
[Channel]
Retail

For home edition, second line should be changed as showed below,

[EditionID]
Home

As per MS Docs {Channel Type} must be either “OEM” or “Retail”.

Sample pid.txt looks like below,

[PID]
Value=YOURP-RODUC-TKEY-IF6V9-RUW32

Reference

How to Reset Windows 10 password

One way to reset password is to reset Windows. Here’s instruction from microsoft support.
Forgot your Windows 10 user password. Here’s a way to fix it if your BIOS is not password protected or if you know the BIOS Password.

Here are the steps to reset password,
First thing to do is to boot using Windows Installation Media (USB boot works),
Then we select “Repair your computer” that gives us access to Troubleshooting. Then we choose command prompt.

After getting access to the command prompt I found that C drive is the Win System Drive. In some cases this can be different. Setup might mark D as system drive. Once you know the system drive it’s pretty easy and we can go to next step.

We rename Utilman binary,

move C:\Windows\System32\Utilman.exe C:\Windows\System32\Utilman.exe.bak

Then we rename cmd.exe,

move C:\Windows\System32\cmd.exe C:\Windows\System32\Utilman.exe

I can verify it,

X:\Sources> dir C:\Windows\System32\Utilman.*
 Volume in drive C is OS
 Volume Serial Number is 3A78-E6F7

 Directory of C:\Windows\System32

03/18/2017  12:57 PM           271,872 Utilman.exe
03/18/2017  12:57 PM            90,112 Utilman.exe.bak
               2 File(s)        361,984 bytes
               0 Dir(s)  462,441,738,240 bytes free

Then we exit command prompt and select “Turn off pc” from the menu. Then we unplug the installation media from the system.

When Windows boots up normally without the installation media, on the logging screen, we click “Ease of access” which brings us “Command Prompt”. That’s golden gate bridge to resetting password.

We add a user using following command syntax,

net user user_name password

Please user_name and password in command above with intended credentials.

Once you are done click Shutdown computer. Now plug in USB boot or DVD installation media again and boot to Windows 10 Setup. Get access to command prompt as mentioned before. Afterwards, restore utilman and cmd.exe as it was before,

move C:\Windows\System32\Utilman.exe C:\Windows\System32\cmd.exe
move C:\Windows\System32\Utilman.exe.bak C:\Windows\System32\Utilman.exe

If you don’t want to type in the commands above, you can copy commands in a script and put inside the USB disk to run them or open using notepad command and copy-paste.

Reference