I would like to know how to write your own async methods the "correct" way.
I have seen many many posts explaining the async/await pattern like this:
http://msdn.microsoft.com/en-us/library/hh191443.aspx
// 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;
}
private void DoIndependentWork()
{
resultsTextBox.Text += "Working........
";
}
This works great for any .NET Method that already implements this functionality like
- System.IO opertions
- DataBase opertions
- Network related operations (downloading, uploading...)
But what if I want to write my own method that takes quite some time to complete where there just is no Method I can use and the heavy load is in the DoIndependentWork
method of the above example?
In this method I could do:
- String manipulations
- Calculations
- Handling my own objects
- Aggregating, comparing, filtering, grouping, handling stuff
- List operations, adding, removing, coping
Again I have stumbled across many many posts where people just do the following (again taking the above example):
async Task<int> AccessTheWebAsync()
{
HttpClient client = new HttpClient();
Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");
await DoIndependentWork();
string urlContents = await getStringTask;
return urlContents.Length;
}
private Task DoIndependentWork()
{
return Task.Run(() => {
//String manipulations
//Calculations
//Handling my own objects
//Aggregating, comparing, filtering, grouping, handling stuff
//List operations, adding, removing, coping
});
}
You may notice that the changes are that DoIndependentWork
now returns a Task and in the AccessTheWebAsync
task the method got an await
.
The heavy load operations are now capsulated inside a Task.Run()
, is this all it takes?
If that's all it takes is the only thing I need to do to provide async Method for every single method in my library the following:
public class FooMagic
{
public void DoSomeMagic()
{
//Do some synchron magic...
}
public Task DoSomeMagicAsync()
{
//Do some async magic... ?!?
return Task.Run(() => { DoSomeMagic(); });
}
}
Would be nice if you could explain it to me since even a high voted question like this:
How to write simple async method? only explains it with already existing methods and just using asyn/await pattern like this comment of the mentioned question brings it to the point:
How to write simple async method?
See Question&Answers more detail:
os