Продолжать обработку после возврата ответа клиенту
У меня есть страница общего обработчика (.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);
}