如何在C#中同步调用异步方法?

时间:2017-11-10 19:14:49

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

我正在为现有功能添加新的Web API调用。我想进行此API调用async,但看起来它会导致死锁。如果我想制作不可能的整个代码频道async,我必须做出更多更改。

我的问题是:

  1. 是否可以从常规方法调用async方法?

  2. 我在这里缺少什么?或者这里的正确方法是什么?

  3. 代码:

    // Exisitng Method
    public Tuple<RestaurantDeliveryProvider, DeliveryHubResult, Task<DeliveryManagerQuoteResponse>> CreateDeliveryRequest(OrderContextDTO orderContextDto)
    {
        var provider = RestaurantBl.GetDeliveryProviderInformationByRestaurantId(orderContextDto.RestaurantId ?? 0);
    
        var deliveryHubResult = RestaurantBl.GetDeliveryHubResult(orderContextDto.OrderId ?? 0);;
    
        // New Call which always comes back with "Not Yet Computed" result
        Task<DeliveryManagerQuoteResponse> deliveryManagerQuoteResponse = _deliveryManager.CreateQuoteRequestAsync(orderContextDto, orderInfo);
    
        return Tuple.Create(provider, deliveryHubResult, deliveryManagerQuoteResponse);
    }
    

    异步方法:

    public async Task<DeliveryManagerQuoteResponse> CreateQuoteRequestAsync(OrderContextDTO orderContextDto, OrderInfoDTO orderInfo)
    {
        DeliveryManagerQuoteResponse deliveryManagerQuoteResponse = null;
    
        try
        {
            var restaurantInfo = RestaurantApi.GetRestaurant(orderInfo.RestaurantId);
            var quoteRequest = new DeliveryManagerQuoteRequest
            {
                DeliveryProvider = null, 
                Country = orderContextDto.DeliveryEstimateRequestDto.RequestedDeliveryAddress.Country,
                Concept = "BK", 
                StoreName = "BK-TEST-US-4", 
                OrderId = orderInfo.OrderId.ToString(),
                AllowCash = false, 
                PaymentType = OrderPaymentType.Prepaid_Credit,
                Note = orderInfo.DeliveryInstructions,
            };
    
            deliveryManagerQuoteResponse = await Quote(quoteRequest);
        }
        catch (Exception ex)
        {
            Log.ErrorFormat("Get Delivery Manager Quote failed: Error: {0}, OrderId: {1}", ex.Message, orderContextDto.OrderId);
        }
    
        return deliveryManagerQuoteResponse;
    }
    
    
    public async Task<DeliveryManagerQuoteResponse> Quote(DeliveryManagerQuoteRequest quoteRequest)
    {
        DeliveryManagerQuoteResponse deliveryManagerQuoteResponse;
    
        var client = HttpClientFactory.GetClient();
        var content = HttpClientFactory.JsonContentFactory.CreateJsonContent(quoteRequest);
        var response = await client.PostAsync("https://myUrl", content);
    
        if (response.IsSuccessStatusCode)
        {
            var data = await response.Content.ReadAsStringAsync();
            deliveryManagerQuoteResponse = JsonConvert.DeserializeObject<DeliveryManagerQuoteResponse>(data);
        }
        else
        {
            throw new Exception((int)response.StatusCode + "-" + response.StatusCode);
        }
    
        return deliveryManagerQuoteResponse;
    }
    

    我也尝试过以下相同的结果:

    public async Task<DeliveryManagerQuoteResponse> Quote(DeliveryManagerQuoteRequest quoteRequest)
    {
        DeliveryManagerQuoteResponse deliveryManagerQuoteResponse;
    
        using (var client = new HttpClient())
        {
            var content = HttpClientFactory.JsonContentFactory.CreateJsonContent(quoteRequest);
            var response = await client.PostAsync("https://myUrl", content);
    
            if (response.IsSuccessStatusCode)
            {
                var data = await response.Content.ReadAsStringAsync();
                deliveryManagerQuoteResponse = JsonConvert.DeserializeObject<DeliveryManagerQuoteResponse>(data);
            }
            else
            {
                throw new Exception((int)response.StatusCode + "-" + response.StatusCode);
            }
        }
    
        return deliveryManagerQuoteResponse;
    }
    

    输出(抱歉输出模糊,如果点击它,你会看到清晰的结果):

    enter image description here

1 个答案:

答案 0 :(得分:2)

  1. 别&#39;吨
  2. 别&#39;吨
  3. 基本上,有一种没有好的或可行的方式从同步方法调用异步方法并等待答案。有异步&#34;同步,但这是反模式,应该积极避免。

    所以:

    1. 将来电者重写为async
    2. 实现API的同步版本