C#

This snippet is taken from MSDN, I think it’s the best sample to illustrate how to use async and await in C#. Sorry for the lack of syntax highlight, I can’t embed Gist because here we have no access within the GFW.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// Three things to note in the signature:
// - The method has an async modifier.
// - The return type is Task or Task<T>. (See "Return Types" section.)
// Here, it is Task<int> because the return statement returns an integer.
// - The method name ends in "Async."
async Task<int> AccessTheWebAsync()
{
// You need to add a reference to System.Net.Http to declare client.
HttpClient client = new HttpClient();

// GetStringAsync returns a Task<string>. That means that when you await the
// task you'll get a string (urlContents).
Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");

// You can do work here that doesn't rely on the string from GetStringAsync.
DoIndependentWork();

// The await operator suspends AccessTheWebAsync.
// - AccessTheWebAsync can't continue until getStringTask is complete.
// - Meanwhile, control returns to the caller of AccessTheWebAsync.
// - Control resumes here when getStringTask is complete.
// - The await operator then retrieves the string result from getStringTask.
string urlContents = await getStringTask;

// The return statement specifies an integer result.
// Any methods that are awaiting AccessTheWebAsync retrieve the length value.
return urlContents.Length;
}

If you want to change your synchronous functions to asynchronous ones, pay attention to the return value type. Use Task for the function that has void as return value type, use Task<T> for the function that use T as return value type.

1
2
void  ->  Task
T -> Task<T>

By the way, you can still use Task<void> for certain purpose, we will talk about this later.

Naming Convention

By convention, it is suggested to append “Async” to the names of methods that have an Async or async modifier.

JavaScript (ES2016, aka ES7)

1
2
3
4
5
6
7
8
9
10
11
12
13
async function mySleep(timeout) {
return new Promise((resolve, reject) => {
setTimeout(function() {
resolve();
}, timeout);
});
}

(async function() {
console.log('Do some thing, ' + new Date());
await mySleep(3000);
console.log('Do other things, ' + new Date());
})();

JavaScript is famous for asynchronous execution, in this example we create a sleep function which is supposed to hold current thread for timeout milliseconds. In the anonymous function, we use two parameters resolve and reject to revoke back to main thread.

The execution result is probably like this:

1
2
Do some thing, Mon Feb 26 2016 21:52:11 GMT+0800 (CST)
Do other things, Mon Feb 26 2016 21:52:14 GMT+0800 (CST)

If you want to run this example, don’t forget to enable ES7 for Node.js.

TypeScript

In the third pick I’d like to show you how to use async/await in TypeScript. It always gives me the feeling that TypeScript and C# share many cool features, at least in the syntax level. Well probably this is what is call Microsoft Style.

1
2
3
4
5
6
7
8
9
10
11
12
async function delay(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}

async function ping(someone: string) {
for (var i = 0; i < 5; i++) {
await delay(1000);
console.log("ping " + someone);
}
}

ping('zp_j');

Ok, like ES7 above, we defined a synchronous function delay which will resolve after ms milliseconds. Then we create a action ping() which will print ping xxxx after the delay of 1 second.

How to run this? Create a TypeScript project with tsc --init, which will generate a tsconfig.json file, change the target to ES6. Here’s my configuration:

1
2
3
4
5
6
{
"compilerOptions": {
"target": "ES6",
"module": "commonjs"
}
}

Run tsc in the folder you will get a JavaScript file with the same filename as your script file. Run it with node, et Voilà.

Furthermore

Here’s the generated file from above ts script, you can ignore this part if you are not interested in how this was implemented by TypeScript.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator.throw(value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments)).next());
});
};
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function ping(someone) {
return __awaiter(this, void 0, void 0, function* () {
for (var i = 0; i < 5; i++) {
yield delay(1000);
console.log("ping " + someone);
}
});
}
ping('zp_j');

* * *

After Everything

How can you generate a title that contains only C# in markdown? Use this:

1
# C&#35;