我对异步/等待的理解是否正确?

时间:2017-11-14 15:58:36

标签: c# asp.net asp.net-mvc asynchronous async-await

根据我的理解,下面的代码最终应该在运行其他代码时检索字符串classification

[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;
}

这应该与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;
}

但是我在await classification上收到错误:&#39; string&#39;不包含&#39; GetAwaiter&#39;

的定义

我不确定为什么会这样。

此外,根据MSDN docs进行昂贵的计算,我应该使用:

property.ClassificationCode = await Task.Run(() => GetClassification(property));

这实际上是实现了我想要的还是只是同步运行?

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:7)

string classification = GetClassification(property);

这是常规同步代码;在分配classification之前,它将不执行任何操作。这听起来像你想要的是:

Task<string> classification = GetClassificationAsync(property);

其中GetClassificationAsync在中间做了一些真正的异步并最终填充Task<string>。请注意,如果GetClassificationAsync仍然同步工作,则代码将继续保持同步。特别是,如果您发现自己使用Task.FromResult:您可能没有做任何事情async

答案 1 :(得分:0)

要与Matthew Jones的代码相同,您必须将代码更改为

[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;
}

但请阅读https://blog.stephencleary.com/2013/11/taskrun-etiquette-examples-dont-use.html为什么不使用ASP.NET