【问题标题】:Bad practice to return from method before async operation completes?在异步操作完成之前从方法返回的坏习惯?
【发布时间】:2016-07-25 05:45:53
【问题描述】:

我有一个 Web API 2 端点,我想在检索和验证用户时异步执行操作。如果此用户不存在,我想像这样返回 404 Not Found:

public async Task<IHttpActionResult> Get()
{
    var getCatTask = GetCatAsync();
    var user = await GetUserAsync();

    if(user == null)
    {
        return NotFound();
    }     

    var cat = await getCatTask;

    return Ok(cat);
}

如果用户等于 null 并且方法在没有等待 getCatTask 的情况下返回,这是否会导致我潜在的问题,或者它被认为是一种不好的做法?

【问题讨论】:

  • 我想出于性能原因,您可以在验证用户时开始获取数据(我认为我不会亲自这样做,因为如果您之前不小心开始向用户发送数据,它会带来潜在的安全风险它已经完成验证,但如果你仔细并且额外的性能真的是必须的那么也许)。但是,如果您返回“未找到”,最好中止异步任务(因为它会浪费处理器时间)。此外,由于数据无法个性化(用户未经过验证),将“GetCat”缓存在某处而不是每次都加载它不是更好吗?

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


【解决方案1】:

这并不是真的糟糕,因为在这种情况下,您只是在读取数据,而您只是会忽略结果。对于每个虚假请求,您都会产生额外的 GetCatAsync 操作成本(这可能不会经常发生)。

如果可能,请考虑将GetCatAsync 设为可取消,然后您至少可以在返回之前开始清理:

public async Task<IHttpActionResult> Get()
{
  var cts = new CancellationTokenSource();
  var getCatTask = GetCatAsync(cts.Token);
  var user = await GetUserAsync();

  if (user == null)
  {
    cts.Cancel();
    return NotFound();
  }     

  var cat = await getCatTask;
  return Ok(cat);
}

【讨论】:

    【解决方案2】:

    这是完全可以接受的。就asyncawait 而言,您没有做错任何事情。关于关键字的几点说明:

    async 关键字只是启用了await 关键字的使用。 await 关键字是所有“魔法”发生的地方,即;当“等待的”异步操作完成时,异步状态机将暂停方法执行并返回到该点。

    一个重要的考虑因素:

    GetCatAsync() 是否返回代表已开始的异步操作的 TaskTask&lt;T&gt;?如果是这样,那可能会有点问题,如果不是,那您就很好,因为稍后等待。不过,我建议添加取消。

    public async Task<IHttpActionResult> Get()
    {
        var cts = new CancellationTokenSource();
        var getCatTask = GetCatAsync(cts.Token);
        var user = await GetUserAsync();
    
        if (user == null)
        {
            cts.Cancel();
            return NotFound();
        }     
    
        var cat = await getCatTask;
        return Ok(cat);
    }
    

    但是,Stephen Cleary 打败了我——上面提到了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多