Cela fonctionne!
Voici ce que je l'ai fait:
Étape 1 & 2 - Méthode d'action est appelée, long fil en cours d'exécution est lancé
Lorsque ma méthode d'action est appelée, il génère un identifiant unique. Je instancie alors une instance de ma classe PdfGenerator
, crée un nouveau thread qui appelle PdfGenerator.Generate
et le démarre.
public class PdfGenerator
{
public string State;
public byte[] Data;
public void Generate()
{
// Generate PDF/Long running process
// Should update State as it goes
// ...
// Once finished, Data is populated with the binary byte[]
}
}
Une fois que le fil a commencé (ou avant de commencer) l'instance du générateur est stocké dans le cache:
HttpContext.Cache[guid] = generator;
Je joins aussi le Guid au ViewData afin qu'il puisse être fait référence à mon avis scénario.
Étape 3 & 4 - Affichage et mise à jour d'état/vue progrès
Maintenant que le fil est en cours d'exécution et la génération de PDF a commencé, je peux afficher mon script de vue de progrès. En utilisant jQuery de $.getJSON
Je suis en mesure de sondage une action distincte pour connaître l'état de la génération:
[OutputCache(Duration = 0, VaryByName = "none", NoStore = true)]
public JsonResult CheckPdfGenerationStatus(string guid)
{
// Get the generator from cache
var generator = HttpContext.Cache[guid] as PdfGenerator;
if (generator == null)
return Json(null);
else
return Json(generator.State);
}
Mon script de vue interprète JSON et affiche les informations de progrès appropriés.
Étape 5 - Présenter le fichier à l'utilisateur
Une fois la génération terminée, l'état des générateurs est réglé en conséquence et quand jQuery reçoit ces informations, il peut soit mettre à la disposition d'un lien, ou envoyer directement le fichier en utilisant javascripts location.href
.
La méthode d'action qui met en place et retourne le fichier est tout simplement le générateur du cache et renvoie l'octet joint []
public ContentResult DownloadPdf(string guid)
{
var generator = HttpContext.Cache[guid] as PdfGenerator;
if (generator == null)
return Content("Error");
if (generator.State == "Completed")
{
return Content(generator.Data);
}
else
{
return Content("Not finished yet");
}
}
Mon mon travail réel que j'ai état plus détaillées telles que Initialisé , En cours d'exécution et terminé. Ainsi qu'un pourcentage de progression (exprimé en décimal, 1.0 étant complet).
Alors ouais, espérons que cela aide quelqu'un d'autre à essayer de faire quelque chose de similaire.
Excellente question ... coincé dans la même situation! –