Author : MD TAREQ HASSAN
Understanding Async and Await
async
keyword indicates- The method contains a long running operation
- The mothod will release execution control right away (execution control will go back to the caller immediately)
- The caller can be normal method or async method
await
keyword- Placed right before a Task i.e. `await Task.Factory.StartNew(delegate/lambda
- The execution controll will come back here once the task (long running operation) is done
Conforming to async method during development
Trick 1
public async Task<T> FetchAsync()
{
return await Task.Factory.StartNew or Task.Run(new Func<T>(() => {
T t = new T();
// modify t
// ... ... ...
return t;
}));
}
Example: Task.Factory.StartNew
public async Task<List<FooModel>> FetchFoosAsync()
{
return await Task.Factory.StartNew(new Func<List<FooModel>>(() => {
var types = new List<FooModel>()
{
new FooModel() { Id = "1" , Name = "Foo 1" },
new FooModel() { Id = "2" , Name = "Foo 2" }
};
return types;
}));
}
Example: Task.Run
public async Task<List<FooModel>> FetchFoosAsync()
{
return await Task.Run(new Func<List<FooModel>>(() => {
var types = new List<FooModel>()
{
new FooModel() { Id = "1" , Name = "Foo 1" },
new FooModel() { Id = "2" , Name = "Foo 2" }
};
return types;
}));
}
Trick 2
await Task.Delay(1);
// or
await Task.Yield();
// do the rest here
// ... ... ...
Examples
// Example 1 - Blazor component
<ChildComponent OnClickCallback="@(async () => { await Task.Yield(); messageText = "Blaze It!"; })" />
// Example 2
private async void button_Click(object sender, EventArgs e)
{
await Task.Yield(); // Make us async right away
var data = ExecuteFooOnUIThread(); // This will run on the UI thread at some point later
await UseDataAsync(data);
}
// Example 3
private static void Main()
{
RecursiveMethod().Wait();
}
private static async Task RecursiveMethod()
{
await Task.Delay(1);
//await Task.Yield(); // Uncomment this line to prevent stackoverlfow.
await RecursiveMethod();
}
More:
- https://stackoverflow.com/a/23436765/4802664
- https://www.it-swarm.dev/ja/c%23/taskyield%EF%BC%88%EF%BC%89%E3%81%AF%E3%81%84%E3%81%A4%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%BE%E3%81%99%E3%81%8B%EF%BC%9F/1044789580/
Extract Result From Async Method
//
// Don't use await: 'var Foo = await FooService.GetFooById("001")' -> 'var task = FooService.GetFooById("001")'
//
// Following trick might not work for Blazor WebAssebmly
var task = FooService.GetFooById("001");
task.Wait();
var fetchedFoo = task.Result;