Why should we use the async method?
The await word provides the feature that allows other processes to continue asynchronously while waiting for the task to finish its job, that is, non-blocking.
For example, when you make an asynchronous web service request, ASP.NET will not use threads between the async method call and the await. It prevents thread starvation.
Authoring Async Methods
async Task MyMethod() { }
which creates a method that can be awaited, but does not return any value,async Task<T> MyReturningMethod { return default(T); }
which creates a method that can be awaited, and returns a value of the type T,private async void Button1_Click(object sender, EventArgs args) { }
async void methods are only suited for UI event handlers
Method 1:
If you want to call a method whose return value is Task, it is sufficient for the current method to start with async.
async MyMethod1
await MyMethod2
async Task MyMethod2
Method 2:
If you need to "call a synchronous method" that does not return Task and you are in a method labeled async, you can use Task.Run. A new thread is opened on the compiler side and the code is run in this thread. Another important point here is that Task.Run can be used with await since it will return Task.
async MyMethod1
await Task.Run(() => { MyMethod2 }
void MyMethod2 (normal method. sync)
public static async Task PushNeworder(string[] deviceIds, string message, string header, string isLogout, object payload)
{
await Task.Run(() =>
{
// sync method
PushToFirebase(deviceIds, isLogout, message, header, payload);
});
}
If you want to return value;
public static async Task<string> AsyncPostData(string apiURL, string data, bool isNETGM)
{
string result = string.Empty;
await Task.Run(() =>
{
result = PostData(apiURL, data, isNETGM);
});
return result;
}
It is recommended to use Task.Run for CPU-related tasks. Since CPU structures contain multiple cores, you can use Task.Run in coding that requires processor power. You can benefit from the core processing power more efficiently by opening a new thread. Task.Run is not recommended if you are performing I/O operations such as file operations and network operations. The reason for this is that there are long waits in I/O operations and this causes the processor core to fall into a waiting state for a while. In addition, care should be taken not to use Task.Run within each other unless necessary.
Let's briefly touch on Task.FromResult and Task.FromException. If there is no result to return, the process is terminated by returning Task.FromResult.
Reference :
https://jaylee.org/archive/2012/07/08/c-sharp-async-tips-and-tricks-part-2-async-void.html
What is the difference between Task.Run with Task.Factory.StartNew?
Task.Run is a shortcut of Task.Factory.StartNew with default parameters.
Task.Run(A);
It is equivalent to :
Task.Factory.StartNew(A, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
ConfigureAwait
In terms of ConfigureAwait, the default value is ConfigureAwait(true). Therefore, if you don’t explicitly specify it, your code will behave as if you used ConfigureAwait(true).
ConfigureAwait(false), I recommend using it for library code and not application code. If you don't write any library code then you probably won't ever have to use it.
You make simple use of await, and the right things happen with regards to callbacks/continuations being posted back to the original context if one existed. This leads to the general guidance:
The setting of downloadBtn.Content = text needs to be done back in the original context.
Right usage :
private static readonly HttpClient s_httpClient = new HttpClient();
private async void downloadBtn_Click(object sender, RoutedEventArgs e)
{
string text = await s_httpClient.GetStringAsync("http://example.com/currenttime");
downloadBtn.Content = text;
}
Wrong usage :
private static readonly HttpClient s_httpClient = new HttpClient();
private async void downloadBtn_Click(object sender, RoutedEventArgs e)
{
string text = await s_httpClient.GetStringAsync("http://example.com/currenttime").ConfigureAwait(false); // bug
downloadBtn.Content = text;
}
The same would go for code in a classic ASP.NET app reliant on HttpContext.Current; using ConfigureAwait(false) and then trying to use HttpContext.Current is likely going to result in problems.
Reference :
https://devblogs.microsoft.com/dotnet/configureawait-faq/
https://blog.stephencleary.com/2023/11/configureawait-in-net-8.html
WaitAll vs. WhenAll what's the difference:
If you have a task that does something with the UI thread (e.g. a task that represents an animation in a Storyboard) if you Task.WaitAll() then the UI thread is blocked and the UI is never updated. if you use await Task.WhenAll() then the UI thread is not blocked, and the UI will be updated.
So;
WaitAll is a blocking call
WhenAll - not - code will continue executing
Use which when:
WaitAll when cannot continue without having the result
WhenAll when what just to be notified, not blocked
References :
https://devblogs.microsoft.com/pfxteam/task-run-vs-task-factory-startnew/https://stackoverflow.com/questions/38423472/what-is-the-difference-between-task-run-and-task-factory-startnewhttps://blog.stephencleary.com/2013/08/startnew-is-dangerous.html
https://www.linkedin.com/pulse/should-i-use-configureawaittrue-configureawaitfalse-viswanathan/