努力在 ASP.net 中进行异步部署

Struggling to get async working on deployment in ASP.net

该代码在我的开发环境中运行良好,但在具有可扩展架构的部署中似乎出现死锁。

Objective 这里是将 API 个请求发送到 SendGrid 的队列,将它们分批处理,一次处理一个批次。

来自 ASHX 处理程序的首次调用

public void ProcessRequest(HttpContext context)
{
    var result = Code.Helpers.Email.Sendgrid.Queue.Process().Result;
    if (result.Success)
    {

Queue.Process()

public static async Task<GenericMethodResult> Process()
{
    var queueItems = GetQueueItemsToProcess();
    var batches = BatchQueueItems(queueItems);

    foreach (var batch in batches)
    {
        var r = await batch.SendToSendGrid();
        if (r.StopBatch)
        {
            break;
        }
    }

    return new GenericMethodResult(true);
}

SendToSendGrid()

public async Task<SendGridAPIMethodResponse> SendToSendGrid()
{
    var r = new SendGridAPIMethodResponse();
    var json = API.Functions.CreateJSONData(this);
    var sg = new SendGridClient(Settings.Email.SendgridAPIKey);

    dynamic response;
    if (Action == Action.UpdateRecipient)
    {
        response = await sg.RequestAsync(SendGridClient.Method.PATCH, urlPath: "contactdb/recipients", requestBody: json);
    }

    string jsonResponse = response.Body.ReadAsStringAsync().Result;
    // Process response...

    return r;
}

我已经尽可能多地删除了代码。

有谁能告诉我为什么这段代码在生产中超时?

SendToSendGrid() 中对 .Result 的阻塞调用导致死锁,因为您正在混合使用异步调用和阻塞调用。

string jsonResponse = response.Body.ReadAsStringAsync().Result;

一直使用异步

var jsonResponse = await response.Body.ReadAsStringAsync();

并尽量避免在异步方法中混合阻塞调用。

您还应该考虑使用 HttpTaskAsyncHandler.

让您的处理程序异步
public class MyHandler : HttpTaskAsyncHandler {
    public override async Task ProcessRequestAsync(HttpContext context) {
        var result = await Code.Helpers.Email.Sendgrid.Queue.Process();
        if (result.Success) {
            //..other code
        }
    }
}