Reputation: 656
I've been trying to find a solution for quite a long time that would show me how to create Asynchronous methods that do not use existing asynchronous code. IE someClass.ActionAsync() I basically have been wanting to do something like
public string GetParsedData(string code){
Console.WriteLine("Starting parser");
var result = "";
foreach(var x in code.Split('\n')){
result += Encode(x);
}
return result;
}
So I understand I must return a Task, but I have found no information on how to await a lambda expression or any other advice on how to break this down. Oddly I think I found the answer from re-sharper giving me dated advice which I will post below.
Upvotes: 5
Views: 5670
Reputation: 656
So Resharper advised me to use TaskEx.Run (which is deprecated) and the proper answer appears to be Task.Run. I've found success rewriting the method as such,
public async Task<string> GetParsedData(string code){
Console.WriteLine("Starting parser");
var taskResult = await Task.Run(() =>
{
var result = "";
foreach(var x in code.Split('\n'))
{
result += Encode(x);
}
return result;
});
return taskResult;
}
Now I can use the await keyword on this method within other async methods as needed.
Upvotes: 0
Reputation: 570
A mandatory read that explains the root of all this discussion much better is Microsoft's "Task-based Asynchronous Pattern", including examples which help to learn it the "good way". The following summary is grabbed from there:
I was also newbie to this, but in summary what I have learned is that you need to distinguish between of IO-work vs. CPU-work. I was greatly inspired from @Stephen Cleary comment above.
xxxxAsync()
functions available in .NET which is preferred mechanism by Microsoft. If your code includes calls to external await xxxxAsync()
, then your function can be regarded as async
as well. In this way, while the CPU is idle waiting for IO, the calling thread is not blocked.xxxxAsync()
function to call, there is an existing wrapper available in .NET to call your code: Task.Factory.StartNew(NET-4.0)
or even easier and better Task.Run(NET-4.5)
, the latter being preferred by Microsoft in this case (*). If your code includes calls to await Task
or returns a Task
, then your function can be regarded as async
as well. In this way, while the intensive task runs in the ThreadPool, the calling thread is not blocked.(*) This mechanism is NOT thought to create async wrappers to your CPU-intensive functions. And specially NEVER do this if you are creating a library. Instead, its the other way around: you should call the existing sync CPU-intensive function from your code by using Task.Run.
Now the best example I have found for the WEB-UI thread blocked by a CPU-intensive operation is here. You can directly go there and skip the theory part.
Upvotes: 6