Продолжать обработку после возврата ответа клиенту

У меня есть страница общего обработчика (.ashx), которая получает документ XML от ведущего поставщика. Затем я беру этот документ XML и отправляю его третьей стороне для подписки. Я жду ответа от третьей стороны, а затем передаю этот ответ ведущему поставщику. Все это происходит за 30 секунд или меньше.

Моя проблема в том, что ведущий поставщик будет ждать не более 30 секунд, прежде чем закрыть соединение и двигаться дальше. Я пытаюсь запустить внутренний таймер, и если я не получил ответ от стороннего страховщика, все равно отправьте ответ ведущему провайдеру. Это все отлично работает.

Что я хочу сделать, так это отправить ответ обратно ведущему провайдеру, но продолжать ждать ответа стороннего страховщика. Они дадут это нам... но иногда это может занять пару минут.

Я перепробовал все виды комбинаций

Response.Flush();
Response.Close();
Response.End();
context.ApplicationInstance.CompleteRequest();

Все, что мне удалось сделать, это а) выдать ошибку о прерывании потока или "Невозможно оценить выражение, потому что код оптимизирован или собственный фрейм находится над стеком вызовов", или б) клиент считает, что запрос был только что завершен, и он так и не получил ответ.

Я не могу реализовать архитектуру типа очереди, не переделав большую часть логики, и даже тогда я не хочу этого делать, потому что это увеличит время обработки ответа.

Какие-либо предложения? Похоже, что.Close() и.End() не предназначены для того, чтобы функционировать так, как я думаю, и я не могу понять, что следует использовать вместо этого.

1 ответ

Решение

Может быть, System.Threading.ThreadPool.QueueUserWorkitem() может вам помочь?

Идея состоит в том, чтобы поставить в очередь операцию, которая будет выполняться всякий раз, когда поток свободен в пуле потоков.

public class Data {
    public int ID {get; set; }
    public string OtherData { get; set; }    
}

public override void ProcessRequest(HttpContext context)
{
    var workLoad = new Data {
        ID = int.Parse(context.Request.Params["ID"]),
        OtherData = context.Request.Params["OtherData"]
    };
    // somewhere before the end :
    ThreadPool.QueueUserWorkItem(new WaitCallback(LongRunningMethod), workLoad);

    Response.Flush();
    Response.Close();
}

public void LongRunningMethod(object state) 
{
    var data = (Data)state;
    CalculateTheOriginOfTheLife(data.ID, data.OtherData);
}
Другие вопросы по тегам