Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Run several examples for ContinueWith, Unwrap, and async-await
public async void TasksAsyncAwait_Tests(int initialNumberOfBooks)
Random rnd = new Random();
LibraryAccount acc = new LibraryAccount(initialNumberOfBooks);
// Run t1, received its result (Task<int>)
Task<int> t1 = BorrowBooks(acc, nameof(t1));
// *********** First example ****************
// After completing t1, continue to another Task
int status = t1.ContinueWith<int>((prevTask) =>
Logger.Log($"After {nameof(t1)} execution, the books inventory is {prevTask.Result}");
// hold the execution of the thread to exemplify how the return is held
return prevTask.Result;
// No need to call Wait, since Task.Result waits for the task to complete
Logger.Log($">>> After running {nameof(t1)} and its successor: {status}");
// *********** Second example ****************
Task<int> t2 = Task.Run<Task<int>>(() =>
return BorrowBooks(acc, nameof(t2));
.Unwrap(); // return Task<int> instead of Task<Task<int>>
Task t3 = t2.ContinueWith((prevTask)=> {
Logger.Log($"After {nameof(t2)} execution, the books inventory is {prevTask.Result}");
// create another thread, without waiting for its return value.
BorrowBooks(acc, nameof(t3));
// To return from this thread only after completing the BorrowBook execution.
//BorrowBooks(acc, nameof(t3)).Wait();
// Waiting for t3, but the its inner thread might not be completed.
Logger.Log($">>> {nameof(t3)} completed");
// *********** Third example ****************
// Starting the task with delay
Task t4 = Task.Delay(rnd.Next(3000, 10000)).ContinueWith((p) => {
Task<int> innerTask = BorrowBooks(acc, nameof(t4));
Logger.Log($">>> Waiting for {nameof(t4)} to complete");
Logger.Log($">>> {nameof(t4)} completed");
Logger.Log($">>> The books inventory is {status}");
// *********** Forth example ****************
// Run the Task, wait until it completes, get its result.
status = await BorrowBooks(acc, "t5");
Logger.Log($">>> The library inventory after t5 is {status}");
// Calling await on t1 to fetch its result (in use-cases when it was still running in the background)
// This exemplifies the usefulness of await.
status = await t1;
Logger.Log($">>> Fetching the library inventory after t1: {status}");
// Local method: it runs a task that withdraws books from the library
Task<int> BorrowBooks(LibraryAccount account, string name)
return Task<int>.Run<int>(() =>
account.WithdrawBooksWithExecuterName(rnd.Next(1, 12), name + ":time="+DateTime.Now.Ticks);
return acc.BorrowedBooksCount;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.