-
-
Save liorksh/77229f8293ba4a9b0b00658701ca4922 to your computer and use it in GitHub Desktop.
Run several examples for ContinueWith, Unwrap, and async-await
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Theory] | |
[InlineData(456)] | |
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 | |
Thread.Sleep(2000); | |
return prevTask.Result; | |
}).Result; | |
// No need to call Wait, since Task.Result waits for the task to complete | |
//t1.Wait(); | |
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. | |
t3.Wait(); | |
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)); | |
innerTask.Wait(); | |
}); | |
Logger.Log($">>> Waiting for {nameof(t4)} to complete"); | |
t4.Wait(); | |
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