Одновременные запросы к обработчику HTTP не работают - PullRequest
3 голосов
/ 12 июня 2009

У меня есть общий обработчик HTTP (* .ashx) в моем приложении ASP.Net, который выполняет некоторые базовые, но трудоемкие вычисления, выводя на экран операторы хода выполнения, чтобы информировать пользователя. Выполнение этих вычислений включает чтение некоторых файлов данных, которые блокируются обработчиком при их использовании, поэтому важно, чтобы два вызова обработчика не начинали обработку сразу.

Для этого я добавил в Cache переменную, которая указывает, что вычисления выполняются, это предотвращает отправку пользователем основного приложения этому обработчику, если другой пользователь уже существует. В самом обработчике он проверяет, установлена ​​ли переменная Cache, и должен отправить пользователя обратно в основное приложение, если установлено значение Cache. Но когда я проверяю это, дважды обращаясь к Handler, один доступ выполняется нормально, а второй сидит там и ничего не делает, пока не завершится первый при запуске. Установка IsReusable в значение true не имеет значения.

У кого-нибудь есть идеи, почему это происходит?

Код ниже:

<code>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("
"); context.Response.Write (""); context.Response.Write ("

Если вы не перенаправлены автоматически, нажмите здесь

"); } private void HandleUpdateProgress (Строковое сообщение) { this._context.Response.Write (message + "\ n"); this._context.Response.Flush (); } public bool IsReusable { получить { вернуть ложь; } } }

Редактировать

Добавлен код с мастер-страницы основного приложения:

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...
}

Ответы [ 3 ]

6 голосов
/ 15 июня 2009

Сам наткнулся на ответ, это не имеет ничего общего с веб-сервером или приложением, а просто связано с поведением браузера. Кажется, что если вы открываете несколько вкладок и переходите по одному и тому же URL-адресу в браузере, таком как Firefox или Chrome, браузер выполняет запросы последовательно, т. Е. Он ждет, пока одна из них завершится, прежде чем делать следующую. Открытие двух браузеров и выполнение двух запросов приводит к ожидаемому поведению

IIS, конвейер Asp.NET и параллелизм

0 голосов
/ 12 июня 2009

Вы уверены, что ваш веб-сервер является многопоточным и может выполнять страницу одновременно? Не могли бы вы добавить операторы print в начале и в конце ProcessRequest и посмотреть, попадете ли вы туда одновременно?

0 голосов
/ 12 июня 2009

Если оба потока читают значение кэша inprogress до того, как один из них его установит, тогда inprogress будет нулевым в обоих случаях.

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

...