Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/265.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# .NetCore WebAPI方法是否与EFCore查询异步_C#_Asynchronous_Asp.net Core_Async Await_Entity Framework Core - Fatal编程技术网

C# .NetCore WebAPI方法是否与EFCore查询异步

C# .NetCore WebAPI方法是否与EFCore查询异步,c#,asynchronous,asp.net-core,async-await,entity-framework-core,C#,Asynchronous,Asp.net Core,Async Await,Entity Framework Core,默认状态下的最佳(或更好)实践是什么?为什么?两者的真正好处是什么? 例如,如果我们在控制器中有Get方法,它应该是: public virtual IActionResult Get(int page = 1, int pageSize = 100) { var q = repository.Query().AsNoTracking().ProjectTo<UserViewModel>(); q = q.Skip((page - 1) * pageSize).Tak

默认状态下的最佳(或更好)实践是什么?为什么?两者的真正好处是什么?
例如,如果我们在控制器中有Get方法,它应该是:

public virtual IActionResult Get(int page = 1, int pageSize = 100)
{
    var q = repository.Query().AsNoTracking().ProjectTo<UserViewModel>();
    q = q.Skip((page - 1) * pageSize).Take(pageSize);
    return new OkObjectResult(q);
}
公共虚拟IActionResult Get(int page=1,int pageSize=100) { var q=repository.Query().AsNoTracking().ProjectTo(); q=q.Skip((第1页)*页面大小)。Take(页面大小); 返回新的OkObjectResult(q); } 或

公共虚拟异步任务Get(int page=1,int pageSize=100) { var q=repository.Query().AsNoTracking().ProjectTo(); q=q.Skip((第1页)*页面大小)。Take(页面大小); 返回新的OkObjectResult(等待q.ToListSync()); } 如果首选async,那么该代码是否适合它并且足够了?
存储库中的Query()也是简单的
公共虚拟IQueryable查询(){return context.Set().AsQueryable();}

我在这里发现,async实际上速度较慢:

该错误显然已修复,但我不知道最新版本中的性能比较是什么。

与常规同步代码相比,
async/await
的好处最大,因为当服务器负载足够大时,释放线程池上的线程会产生不同。在此之前,上下文跟踪和切换的开销很容易大于释放线程的性能增益

我倾向于使用异步API而不是同步API,主要是因为我参与过一些项目,在这些项目中,高负载和同步代码是一个非常严重的问题,以至于有人认为是时候重构并转向
async
,而且每次都很痛苦。仅公开
async
API:s也变得越来越普遍(例如,Azure SDK有许多
async
操作没有同步对应项),这意味着如果您最终使用这样的API,您可能必须在以后执行这样的重写

但是,如果性能是唯一需要考虑的因素,那么您需要在实际负载下分析应用程序,并查看哪种方法最有效


增编:

引入更多的
异步
/
等待
开销比必要的开销要容易得多。我喜欢使用的一条经验法则是,考虑三种类型的方法,它们可以返回
Task
Task
,并分别遵循以下模式之一:

  • 实际同步的方法(但返回
    任务
    任务
    ,例如为了允许异步变量重载):返回
    任务。FromResult

    public Task<string> ActuallySynchronousGetter()
    {
        return Task.FromResult("foo");
    }
    
  • 实际的异步方法,既执行异步操作(通常是I/O),又处理异步操作的结果:这是您实际需要
    async
    wait
    关键字的唯一时间


    详细介绍了
    async
    await
    的工作原理,以及您应该(和不应该)如何使用它。

    与常规同步代码相比,
    async/await
    的好处最大,因为当您的服务器负载足够重时,释放线程池中的线程会有所不同。在此之前,上下文跟踪和切换的开销很容易大于释放线程的性能增益

    我倾向于使用异步API而不是同步API,主要是因为我参与过一些项目,在这些项目中,高负载和同步代码是一个非常严重的问题,以至于有人认为是时候重构并转向
    async
    ,而且每次都很痛苦。仅公开
    async
    API:s也变得越来越普遍(例如,Azure SDK有许多
    async
    操作没有同步对应项),这意味着如果您最终使用这样的API,您可能必须在以后执行这样的重写

    但是,如果性能是唯一需要考虑的因素,那么您需要在实际负载下分析应用程序,并查看哪种方法最有效


    增编:

    引入更多的
    异步
    /
    等待
    开销比必要的开销要容易得多。我喜欢使用的一条经验法则是,考虑三种类型的方法,它们可以返回
    Task
    Task
    ,并分别遵循以下模式之一:

    • 实际同步的方法(但返回
      任务
      任务
      ,例如为了允许异步变量重载):返回
      任务。FromResult

      public Task<string> ActuallySynchronousGetter()
      {
          return Task.FromResult("foo");
      }
      
    • 实际的异步方法,既执行异步操作(通常是I/O),又处理异步操作的结果:这是您实际需要
      async
      wait
      关键字的唯一时间


      详细介绍了
      async
      await
      的工作原理,以及您应该(和不应该)如何使用它。

      第一个线程将阻止请求线程,因此在高负载/流量情况下,一旦所有线程用完,它将很快开始向调用者返回http 500错误。请注意,以后使用正确的标签!第一个线程将阻塞请求线程,因此在高负载/流量场景中,当所有线程用完后,它将很快开始向调用者返回http 500错误。请注意,以后使用正确的标签!那么第二个示例中的代码是否可以,特别是async Wait代码是否只能在控制器中按原样离开存储库?@borisdj请参阅我的更新答案以了解更多指导原则。就像您的代码一样。由于repository.Query(),第三种情况下失败了,如果是这样,那么该方法应该是什么样子?我认为您当前对
      repository.Query()
      的实现很好。现在我有点困惑了,到底是什么问题
      // note: no async/await, just Task<T>
      public Task<string> ForwardingGetter()
      {
           return SomeOtherGetter(); // also with return type Task<string>
      }
      
      public async Task<string> GetStringAsynchronously()
      {
           var str = await SomeOtherGetter();
           return str.Replace("foo", "bar"); // note: we need the actual string here
      }
      
      var data = await repository.Query()
          .AsNoTracking()
          .ProjectTo<UserViewModel>()
          .Skip((page - 1) * pageSize)
          .Take(pageSize)
          .ToListAsync();
      return new OkObjectResult(data);