Reputation: 193
from what I understand the code below should eventually retrieve the string classification
while running other code.
[HttpPost]
public async Task<ActionResult> CreatePropertyAsync(Property property)
{
string classification = GetClassification(property);
// GetClassification() runs a complex calculation but we don't need
// the result right away so the code can do other things here related to property
// ... code removed for brevity
property.ClassificationCode = await classification;
// all other code has been completed and we now need the classification
db.Properties.Add(property);
db.SaveChanges();
return RedirectToAction("Details", new { id = property.UPRN });
}
public string GetClassification(Property property)
{
// do complex calculation
return classification;
}
This should work the same way as in the below code from Matthew Jones' article
public async Task<string> GetNameAndContent()
{
var nameTask = GetLongRunningName(); //This method is asynchronous
var content = GetContent(); //This method is synchronous
var name = await nameTask;
return name + ": " + content;
}
However I get an error on await classification
: 'string' does not contain a definition for 'GetAwaiter'
I'm unsure why this is happening.
Additionally, according to MSDN docs for expensive calculations I should instead be using:
property.ClassificationCode = await Task.Run(() => GetClassification(property));
Is this actually achieving what I want or is this just running synchronously anyway?
Thanks in advance for help.
Upvotes: 0
Views: 150
Reputation: 19106
To have the same as in the code from Matthew Jones you have to change your code to
[HttpPost]
public async Task<ActionResult> CreatePropertyAsync(Property property)
{
Task<string> classificationTask = Task.Run( () => GetClassification(property) );
// GetClassification() runs a complex calculation but we don't need
// the result right away so the code can do other things here related to property
// ... code removed for brevity
property.ClassificationCode = await classificationTask;
// all other code has been completed and we now need the classification
db.Properties.Add(property);
db.SaveChanges();
return RedirectToAction("Details", new { id = property.UPRN });
}
public string GetClassification(Property property)
{
// do complex calculation
return classification;
}
But read https://blog.stephencleary.com/2013/11/taskrun-etiquette-examples-dont-use.html why not with ASP.NET
Upvotes: 0
Reputation: 1063754
string classification = GetClassification(property);
this is regular synchronous code; it will do nothing until classification
is assigned. It sounds like what you want is:
Task<string> classification = GetClassificationAsync(property);
where GetClassificationAsync
does something genuinely async in the middle and eventually populates a Task<string>
. Note that if GetClassificationAsync
still works synchronously, the code will all continue to be synchronous. In particular, if you find yourself using Task.FromResult
: you probably aren't doing anything async
.
Upvotes: 7