Dans mon application Web, j'utilise wkhtmltopdf
pour traiter les rapports afin de les afficher au format PDF. J'ai quelques fonctions qui compilent du code HTML ensemble, des en-têtes, etc., puis transmettent cette information à wkhtmltopdf
pour compiler le PDF et le servir à l'utilisateur.Le verrouillage des fonctions et l'utilisation de Mutex se comportent différemment dans IIS Express et IIS
Quelque chose comme:
public JsonResult BuildPDF(string one, string two, SomeData[] data, SomeList[] {
lock(PDFLock) {
// ... Code here to compile HTML and save to files
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = @"C:\inetpub\wwwroot\MySite\wkhtmltopdf.exe";
psi.UseShellExecute = true;
psi.Verb = "runas";
...
Process p = Process.Start(psi);
p.WaitForExit();
}
}
Une fois le PDF est compilé je pousse à l'utilisateur puis supprimez le fichier.
Comme vous pouvez le voir, j'ai un verrou autour de cette fonction pour éviter deux tentatives de traitement d'un PDF à la fois. Sur IIS Express
cette fonction se comporte comme je m'y attendrais: si deux demandes sont faites exactement au même moment, la requête qui le fait en premier sera traitée, et la deuxième requête s'asseoira et attendra sur le verrou jusqu'à ce que la première demande soit complète .
Dans la version IIS, il semble ignorer ce verrou, et n'attend pas la fin de la première demande. Il finit par sauter la fonction si rapidement que la première demande est en cours d'exécution tandis que la deuxième demande se termine (sans succès), de sorte que l'utilisateur reçoit un message indiquant que la demande a échoué.
Je ne suis pas sûr pourquoi il ignorerait ce verrou, ou pourquoi il fonctionnerait dans le débogage (IIS Express).
Y a-t-il une possibilité que cela soit dû à la configuration d'IIS?
Edit:
Le problème avec lock
était un problème de processus de travail dans IIS. Je suis en train de tester Mutex maintenant avec plusieurs processus.
Edit:
utilisation Mutex: le Mutex est déclaré dans la classe comme private static Mutex mut = new Mutex();
public JsonResult BuildPDF(string one, string two, SomeData[] data, SomeList[] {
mut.WaitOne();
// ... Code here to compile HTML and save to files
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = @"C:\inetpub\wwwroot\MySite\wkhtmltopdf.exe";
psi.UseShellExecute = true;
psi.Verb = "runas";
...
Process p = Process.Start(psi);
p.WaitForExit();
//... Return some JSON to user
}
Puis dans la méthode Download
:
public virtual void Download() {
// ... Response headers and stuff
Response.TransmitFile(@"C:\inetpub\wwwroot\MySite\temppdfs\pdfout.pdf");
Response.End();
System.IO.File.Delete(@"C:\inetpub\wwwroot\MySite\temppdfs\pdfout.pdf");
mut.ReleaseMutex();
}
Ma compréhension est que 'Process.Start' ne bloquera pas le thread courant (c'est-à-dire que l'exécution continuera après le démarrage du processus). Si cela est vrai, votre verrou sera libéré pendant que votre processus est en cours d'exécution. – AndySavage
Hmm peut-être que c'est le cas, mais je ne sais pas pourquoi cela fonctionne correctement dans IIS Express alors: S – sosil
Je devrais également noter que j'ai p.WaitForExit(), que j'espérais bloquer jusqu'à ce que le processus est sorti – sosil