为什么要创建异步WebAPI操作而不是同步操作?

2020/11/16 05:11 · jquery ·  · 0评论

我在创建的Web API中执行以下操作:

// GET api/<controller>
[HttpGet]
[Route("pharmacies/{pharmacyId}/page/{page}/{filter?}")]
public CartTotalsDTO GetProductsWithHistory(Guid pharmacyId, int page, string filter = null ,[FromUri] bool refresh = false)
{
    return delegateHelper.GetProductsWithHistory(CustomerContext.Current.GetContactById(pharmacyId), refresh);
}

通过以下方式通过Jquery Ajax调用完成对此Web服务的调用:

$.ajax({
      url: "/api/products/pharmacies/<%# Farmacia.PrimaryKeyId.Value.ToString() %>/page/" + vm.currentPage() + "/" + filter,
      type: "GET",
      dataType: "json",
      success: function (result) {
          vm.items([]);
          var data = result.Products;
          vm.totalUnits(result.TotalUnits);
      }          
  });

我已经看到一些开发人员以这种方式实现了先前的操作:

// GET api/<controller>
[HttpGet]
[Route("pharmacies/{pharmacyId}/page/{page}/{filter?}")]
public async Task<CartTotalsDTO> GetProductsWithHistory(Guid pharmacyId, int page, string filter = null ,[FromUri] bool refresh = false)
{
    return await Task.Factory.StartNew(() => delegateHelper.GetProductsWithHistory(CustomerContext.Current.GetContactById(pharmacyId), refresh));
}

不过要说,GetProductsWithHistory()是一个相当长的操作。考虑到我的问题和上下文,使webAPI操作异步将给我带来什么好处?

在您的特定示例中,该操作完全不是异步的,因此您要做的是异步同步。您只是释放一个线程而阻塞另一个线程。不需要这样做,因为所有线程都是线程池线程(与GUI应用程序不同)。

在关于“异步同步”的讨论中,我强烈建议,如果您有一个内部实现同步的API,则不应公开仅将同步方法包装在中的异步对象Task.Run

我应该公开异步方法的同步包装器吗?

但是,在进行WebAPI调用的async地方有实际的异步操作(通常是I / O),而不是阻塞坐在并等待结果的线程,该线程返回线程池并可以执行其他一些操作。总而言之,这意味着您的应用程序可以用更少的资源做更多的事情,并提高可伸缩性。

一种方法可能是(我已在客户应用程序中成功使用过此方法)让Windows Service运行带有辅助线程的冗长操作,然后在IIS中执行此操作以释放线程,直到阻塞操作完成:注意,这是假定的结果存储在一个表(由jobId标识的行)中,并且在使用后数小时便进行了更清洁的清理过程。

要回答这个问题,“鉴于我的问题和背景,使webAPI操作异步对我有什么好处?” 考虑到它是“相当长的操作”,我在想很多秒而不是毫秒,所以这种方法可以释放IIS线程。显然,您还必须运行Windows服务,该服务本身会占用资源,但是这种方法可以防止大量慢速查询窃取系统其他部分的线程。

// GET api/<controller>
[HttpGet]
[Route("pharmacies/{pharmacyId}/page/{page}/{filter?}")]
public async Task<CartTotalsDTO> GetProductsWithHistory(Guid pharmacyId, int page, string filter = null ,[FromUri] bool refresh = false)
{
        var jobID = Guid.NewGuid().ToString()
        var job = new Job
        {
            Id = jobId,
            jobType = "GetProductsWithHistory",
            pharmacyId = pharmacyId,
            page = page,
            filter = filter,
            Created = DateTime.UtcNow,
            Started = null,
            Finished = null,
            User =  {{extract user id in the normal way}}
        };
        jobService.CreateJob(job);

        var timeout = 10*60*1000; //10 minutes
        Stopwatch sw = new Stopwatch();
        sw.Start();
        bool responseReceived = false;
        do
        {
            //wait for the windows service to process the job and build the results in the results table
            if (jobService.GetJob(jobId).Finished == null)
            {
                if (sw.ElapsedMilliseconds > timeout ) throw new TimeoutException();
                await Task.Delay(2000);
            }
            else
            {
                responseReceived = true;
            }
        } while (responseReceived == false);

    //this fetches the results from the temporary results table
    return jobService.GetProductsWithHistory(jobId);
}
本文地址:http://jquery.askforanswer.com/weishenmeyaochuangjianyibuwebapicaozuoerbushitongbucaozuo.html
文章标签: ,   ,   ,   ,  
版权声明:本文为原创文章,版权归 admin 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!