У меня есть общий HTTP-обработчик (* .ashx) в моем приложении ASP.Net, который выполняет некоторые базовые, но трудоемкие вычисления, распечатывая заявления о выполнении на выходе, поскольку он идет, чтобы информировать пользователя , Выполнение этих вычислений включает в себя чтение некоторых файлов данных, которые блокируются обработчиком при их использовании, поэтому важно, чтобы два вызова обработчика не запускались сразу.Одновременные запросы к обработчику HTTP не работают
Для этого я добавил переменную в кэш, которая указывает, что выполняется вычисление, это предотвращает отправку основного приложения в этот обработчик, если другой пользователь уже существует. В самом обработчике он проверяет, установлена ли переменная Cache и должна отправить пользователя обратно в основное приложение, если установлено значение Cache. Но когда я проверяю это, дважды обращаясь к обработчику, один доступ выполняется отлично, а второй сидит там и ничего не делает, пока первый не завершится, когда он запустится. Установка IsReusable в true не имеет значения.
У кого-нибудь есть идеи, почему это происходит?
код ниже:
public class UpdateStats : IHttpHandler
{
private HttpContext _context;
public const String UpdateInProgressCacheKey = "FAHLeagueWebUpdateInProgress";
public void ProcessRequest(HttpContext context)
{
//Use a Cache variable to ensure we don't call multiple updates
Object inprogress = context.Cache[UpdateInProgressCacheKey];
if (inprogress != null)
{
//Already updating
context.Response.Redirect("Default.aspx");
}
else
{
//Set the Cache variable so we know an Update is happening
context.Cache.Insert(UpdateInProgressCacheKey, true, null, DateTime.Now.AddMinutes(10), Cache.NoSlidingExpiration);
}
context.Response.Clear();
context.Response.ContentType = "text/html";
this._context = context;
context.Response.Write("<pre>Please wait while we Update our Statistics, you will be automatically redirected when this finishes...\n\n");
//Get the Stats
Statistics stats = new Statistics(context.Server);
//Subscribe to Update Progress Events
stats.UpdateProgress += this.HandleUpdateProgress;
//Update
String force = context.Request.QueryString["force"];
stats.UpdateStats((force != null));
//Remove the Cache variable
context.Cache.Remove(UpdateInProgressCacheKey);
context.Response.Write("</pre>");
context.Response.Write("<meta http-equiv=\"refresh\" content=\"0;URL=Default.aspx\" />");
context.Response.Write("<p>If you are not automatically redirected please click <a href=\"Default.aspx\">here</a></p>");
}
private void HandleUpdateProgress(String message)
{
this._context.Response.Write(message + "\n");
this._context.Response.Flush();
}
public bool IsReusable
{
get
{
return false;
}
}
}
Редактировать
Добавлен код из мастер-страницы основного приложения:
public partial class FAH : System.Web.UI.MasterPage
{
private Statistics _stats;
protected void Page_Init(object sender, EventArgs e)
{
this._stats = new Statistics(this.Server);
if (this._stats.StatsUpdateNeeded)
{
//If the Cache variable is set we're already updating
Object inprogress = Cache[UpdateStats.UpdateInProgressCacheKey];
if (inprogress != null) this.Response.Redirect("UpdateStats.ashx");
}
}
//etc...
}
Я думаю, что может случиться, но это приведет лишь к основному приложению перенаправляет запросы назад к обработчику в любом случае, так как, если обновление не произойдет, тогда основное приложение все равно захочет обновить – RobV
Я думаю, что наличие обоих потоков с нулевым кешем означает, что вы можете нажать контекст.Cache.Insert дважды, чтобы вы не блокировали второй запрос. Но это не проблема, которую вы описываете. Также может возникнуть подобная проблема синхронизации с линией «if (inprogress! = Null) this.Response.Redirect (« UpdateStats.ashx »); так как это должно будет вернуть обратно в браузер, чтобы перенаправить на обработчик. Как вы делаете свои 2 тестовых запроса? это в том же браузере? –