【问题标题】:Is my understanding of async/await correct?我对 async/await 的理解是否正确?
【发布时间】:2018-04-27 15:44:42
【问题描述】:

据我了解,下面的代码最终应该在运行其他代码时检索字符串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 上收到错误:“字符串”不包含“GetAwaiter”的定义

我不确定为什么会这样。

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

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

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

提前感谢您的帮助。

【问题讨论】:

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


【解决方案1】:
string classification = GetClassification(property);

这是常规同步代码;在分配classification 之前,它什么也不做。听起来你想要的是:

Task<string> classification = GetClassificationAsync(property);

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

【讨论】:

  • GetClassification 的返回类型呢?那不应该是Task&lt;string&gt;
  • @Shyju 如果你的意思是GetClassificationAsync - 那么是的,它确实应该是
  • 如果 GetClassification 仅受 CPU 限制,则不应使其异步,而是使用 Task.Run => blog.stephencleary.com/2013/11/… 在最高级别调用它
【解决方案2】:

要与 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

【讨论】:

    猜你喜欢
    • 2021-07-30
    • 2017-04-10
    • 2015-11-01
    • 2016-01-09
    • 2021-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多