J'ai un gestionnaire HTTP générique (* .ashx) dans mon application ASP.Net qui effectue des calculs de base, mais qui prennent du temps, en imprimant des instructions de progression à la sortie pour que l'utilisateur reste informé . L'exécution de ces calculs implique la lecture de certains fichiers de données qui sont verrouillés par le gestionnaire lors de leur utilisation, il est donc important que deux appels au gestionnaire ne démarrent pas le traitement à la fois. Pour y parvenir, j'ai ajouté une variable dans le cache qui indique que le calcul est en cours, ce qui empêche l'application principale d'envoyer un utilisateur à ce gestionnaire si un autre utilisateur s'y trouve déjà. Dans le gestionnaire lui-même, il vérifie si la variable cache est définie et doit renvoyer l'utilisateur à l'application principale si la valeur du cache est définie. Mais quand je teste ceci en accédant au Handler deux fois, un accès s'exécute bien et le second reste là et ne fait rien jusqu'à ce que le premier se termine quand il s'exécute. Définir IsReusable sur true ne fait aucune différence.Les demandes simultanées à un gestionnaire HTTP ne fonctionnent pas
Quelqu'un at-il des idées pourquoi cela se produit?
code ci-dessous:
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;
}
}
}
Modifier
Ajouté le code de la page maître de l'application principale:
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...
}
Je suppose que cela pourrait se produire, mais cela ne ferait que donner lieu à l'application principale de rediriger les requêtes vers le gestionnaire de toute façon, car si la mise à jour ne fonctionne pas arrive alors l'application principale voudra toujours une mise à jour – RobV
Je pense qu'avoir les deux threads avec un cache nul signifie que vous pouvez frapper context.Cache.Insert deux fois, donc vous ne bloquerez pas la deuxième requête. Mais ce n'est pas le problème que vous décrivez. Il peut également y avoir un problème de synchronisation similaire avec la ligne "if (inprogress! = Null) this.Response.Redirect (" UpdateStats.ashx ");" car cela devra faire un aller retour au navigateur pour rediriger vers le gestionnaire. Comment faites-vous vos 2 demandes de test? est-ce dans le même navigateur? –