gpt4 book ai didi

c# - Web 服务性能/吞吐量的异步方法

转载 作者:行者123 更新时间:2023-11-30 16:50:54 38 4
gpt4 key购买 nike

我正在尝试弄清楚在使用 HttpClient 将 POST 发送到外部 API 时,使用 aysnc/await 是否有助于提高应用程序吞吐量。

场景:我有一个将 POST 数据发送到支付处理器 Web API 的类。 POST 付款有 4 个步骤:1 - 发布联系人2 - POST交易3 - 捐赠后4 - POST 信用卡付款

步骤 1 - 4 必须按照上面指定的顺序依次进行。

在等待支付处理器的响应时,我的应用程序没有任何“繁忙的工作”要做——在这种情况下,对以下操作使用 async/await 是否有意义?它会在高容量期间增加应用程序吞吐量吗?谢谢!

编辑:(问题被标记为不清楚)1.我的应用程序是一个web api(微服务)2. 我正在使用 .Result(阻塞)来避免异步/等待(显然这是错误的!)3. 我们将有 1000 个请求/分钟的“尖峰”负载

    public virtual ConstituentResponse PostConstituent(Constituent constituent)
{
var response = PostToUrl<Constituent>("/api/Constituents", constituent);
if (!response.IsSuccessStatusCode)
HandleError(response);

return response.Content.ReadAsAsync<ConstituentResponse>().Result;
}

public virtual TransactionResponse PostTransaction(Transaction transaction)
{
var response = PostToUrl<Transaction>("/api/Transactions", transaction);
if (!response.IsSuccessStatusCode)
HandleError(response);

return response.Content.ReadAsAsync<TransactionResponse>().Result;
}

public virtual DonationResponse PostDonation(Donation donation)
{
var response = PostToUrl<Donation>("/api/Donations", donation);
if (!response.IsSuccessStatusCode)
HandleError(response);

return response.Content.ReadAsAsync<DonationResponse>().Result;
}

public virtual CreditCardPaymentResponse PostCreditCardPayment(CreditCardPayment creditCardPayment)
{
var response = PostToUrl<CreditCardPayment>("/api/CreditCardPayments", creditCardPayment);
if (!response.IsSuccessStatusCode)
HandleError(response);

return response.Content.ReadAsAsync<CreditCardPaymentResponse>().Result;
}

protected virtual HttpResponseMessage PostToUrl<T>(string methodUri, T value)
{
return _httpClient.PostAsJsonAsync(methodUri, value).Result;
}

上面的五个方法是从另一个类/函数调用的:

public virtual IPaymentResult Purchase(IDonationEntity donation, ICreditCard creditCard)
{

var constituentResponse = PostConstituent(donation);
var transactionResponse = PostTransaction(donation, constituentResponse);
var donationResponse = PostDonation(donation, constituentResponse, transactionResponse);
var creditCardPaymentResponse = PostCreditCardPayment(donation, creditCard, transactionResponse);

var paymentResult = new PaymentResult
{
Success = (creditCardPaymentResponse.Status == Constants.PaymentResult.Succeeded),
ExternalPaymentID = creditCardPaymentResponse.PaymentID,
ErrorMessage = creditCardPaymentResponse.ErrorMessage
};

return paymentResult;
}

最佳答案

不能在这里实际使用await Task.WhenAll,因为当您购买下一个异步操作时依赖于前一个的结果。因此,您需要让它们以序列化的方式执行。但是,仍然强烈建议您对此类 I/O 使用 async/await,即;网络服务调用。

代码是使用 Async* 方法调用编写的,但实际上并没有使用该模式——它是阻塞的,可能会导致死锁以及不良的性能影响。您应该只在控制台应用程序中使用 .Result(和 .Wait())。理想情况下,您应该使用 async/await。这是调整代码的正确方法。

public virtual async Task<ConstituentResponse> PostConstituenAsync(Constituent constituent)
{
var response = await PostToUrlAsync<Constituent>("/api/Constituents", constituent);
if (!response.IsSuccessStatusCode)
HandleError(response);

return await response.Content.ReadAsAsync<ConstituentResponse>();
}

public virtual async Task<TransactionResponse PostTransactionAsync(Transaction transaction)
{
var response = await PostToUrl<Transaction>("/api/Transactions", transaction);
if (!response.IsSuccessStatusCode)
HandleError(response);

return await response.Content.ReadAsAsync<TransactionResponse>();
}

public virtual async Task<DonationResponse> PostDonationAsync(Donation donation)
{
var response = await PostToUrl<Donation>("/api/Donations", donation);
if (!response.IsSuccessStatusCode)
HandleError(response);

return await response.Content.ReadAsAsync<DonationResponse>();
}

public virtual async Task<CreditCardPaymentResponse> PostCreditCardPaymentAsync(CreditCardPayment creditCardPayment)
{
var response = await PostToUrlAsync<CreditCardPayment>("/api/CreditCardPayments", creditCardPayment);
if (!response.IsSuccessStatusCode)
HandleError(response);

return await response.Content.ReadAsAsync<CreditCardPaymentResponse>();
}

protected virtual Task<HttpResponseMessage> PostToUrlAsync<T>(string methodUri, T value)
{
return _httpClient.PostAsJsonAsync(methodUri, value);
}

用法

public virtual await Task<IPaymentResult> PurchaseAsync(IDonationEntity donation, ICreditCard creditCard)
{
var constituentResponse = await PostConstituentAsync(donation);
var transactionResponse = await PostTransactionAsync(donation, constituentResponse);
var donationResponse = await PostDonationAsync(donation, constituentResponse, transactionResponse);
var creditCardPaymentResponse = await PostCreditCardPaymentAsync(donation, creditCard, transactionResponse);

var paymentResult = new PaymentResult
{
Success = (creditCardPaymentResponse.Status == Constants.PaymentResult.Succeeded),
ExternalPaymentID = creditCardPaymentResponse.PaymentID,
ErrorMessage = creditCardPaymentResponse.ErrorMessage
};

return paymentResult;
}

关于c# - Web 服务性能/吞吐量的异步方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34324443/

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com