programing tip

동기화 작업 대신 비동기 WebAPI 작업을 만들어야하는 이유는 무엇입니까?

itbloger 2020. 8. 6. 08:03
반응형

동기화 작업 대신 비동기 WebAPI 작업을 만들어야하는 이유는 무엇입니까?


내가 만든 웹 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 호출을 통해 수행됩니다.

$.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.

에서 해야 내가 비동기 메서드에 대한 동기 래퍼를 노출?

그러나 async스레드가 결과를 기다리는 스레드를 차단하는 대신 실제 비동기 작업 (일반적으로 I / O)이있는 곳에서 WebAPI를 호출 하면 스레드가 스레드 풀로 돌아가서 다른 작업을 수행 할 수 있습니다. 무엇보다도 애플리케이션이 적은 리소스로 더 많은 것을 할 수 있고 확장 성이 향상됩니다.


한 가지 접근 방식은 (고객 응용 프로그램에서이를 성공적으로 사용했습니다) Windows 서비스가 작업자 스레드로 긴 작업을 실행하도록하고 IIS 에서이 작업을 수행하여 차단 작업이 완료 될 때까지 스레드를 해제 할 수 있습니다. 결과는 테이블 (jobId로 식별 된 행)에 저장되고 사용 후 몇 시간 후에 정리 프로세스가 정리됩니다.

"문제와 상황을 설명하면 webAPI 작업을 비 동기화하면 어떤 이점이 있습니까?"라는 질문에 대답하려면 "긴 작업"이라고 생각하면 ms가 아니라 몇 초가 걸리는 것 같습니다.이 방법은 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);
}

참고URL : https://stackoverflow.com/questions/26158789/why-should-i-create-async-webapi-operations-instead-of-sync-ones

반응형