TridentTrue
TridentTrue

Reputation: 193

Is my understanding of async/await correct?

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

Answers (2)

Sir Rufo
Sir Rufo

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

Marc Gravell
Marc Gravell

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

Related Questions