IIS Express 和 IIS 中功能锁和互斥量的使用行为不同
Function lock and Mutex usage behaving differently in IIS Express and IIS
在我的 Web 应用程序中,我使用 wkhtmltopdf
处理报告以将其输出为 PDF。我有一些函数可以将一些 HTML 编译在一起,一些 headers 等,然后将此信息传递给 wkhtmltopdf
以编译 PDF 并将其提供给用户。
类似于:
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();
}
}
编译 PDF 后,我将其推送给用户,然后删除文件。
如您所见,我对该函数进行了锁定,以防止两次尝试同时处理一个 PDF。 在 IIS Express
上,此函数的行为符合我的预期:如果同时发出两个请求,则第一个发出请求的请求将被处理,第二个请求将等待锁定直到第一个请求完成。
在发布的 IIS 中,它似乎忽略了这个锁,并且不等待第一个请求完成。它实际上最终跳过了这个函数,以至于第一个请求 still 运行 而第二个请求完成(不成功),所以用户收到一条请求失败的消息.
我不确定为什么它会忽略这个锁,或者为什么它会在调试 (IIS Express) 中工作。
这是否可能是 IIS 配置的问题?
编辑:
lock
的问题是 IIS 中多个工作进程的问题。我现在正在使用多个进程再次测试 Mutex。
编辑:
Mutex 用法:Mutex 在 class 中声明为 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
}
然后在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();
}
我对 lock
和 Mutex
用法的理解有点偏差。
lock
不工作的原因是我在 IIS 中的应用程序池允许多个工作进程 (4),因此锁无法跨进程工作。
我在函数外声明 Mutex
时使用不当,现在 Mutex
在我的例子中的正确用法(在应用程序池中发布带有多个进程的 IIS):
public JsonResult BuildPDF(string one, string two, SomeData[] data, SomeList[] {
Mutex mut = new Mutex(false, @"Global\PDFMutex");
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();
mut.ReleaseMutex();
//... Return some JSON to user
}
Mutex
的这种用法在多个进程和多个函数中似乎是成功的。
在我的 Web 应用程序中,我使用 wkhtmltopdf
处理报告以将其输出为 PDF。我有一些函数可以将一些 HTML 编译在一起,一些 headers 等,然后将此信息传递给 wkhtmltopdf
以编译 PDF 并将其提供给用户。
类似于:
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();
}
}
编译 PDF 后,我将其推送给用户,然后删除文件。
如您所见,我对该函数进行了锁定,以防止两次尝试同时处理一个 PDF。 在 IIS Express
上,此函数的行为符合我的预期:如果同时发出两个请求,则第一个发出请求的请求将被处理,第二个请求将等待锁定直到第一个请求完成。
在发布的 IIS 中,它似乎忽略了这个锁,并且不等待第一个请求完成。它实际上最终跳过了这个函数,以至于第一个请求 still 运行 而第二个请求完成(不成功),所以用户收到一条请求失败的消息.
我不确定为什么它会忽略这个锁,或者为什么它会在调试 (IIS Express) 中工作。
这是否可能是 IIS 配置的问题?
编辑:
lock
的问题是 IIS 中多个工作进程的问题。我现在正在使用多个进程再次测试 Mutex。
编辑:
Mutex 用法:Mutex 在 class 中声明为 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
}
然后在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();
}
我对 lock
和 Mutex
用法的理解有点偏差。
lock
不工作的原因是我在 IIS 中的应用程序池允许多个工作进程 (4),因此锁无法跨进程工作。
我在函数外声明 Mutex
时使用不当,现在 Mutex
在我的例子中的正确用法(在应用程序池中发布带有多个进程的 IIS):
public JsonResult BuildPDF(string one, string two, SomeData[] data, SomeList[] {
Mutex mut = new Mutex(false, @"Global\PDFMutex");
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();
mut.ReleaseMutex();
//... Return some JSON to user
}
Mutex
的这种用法在多个进程和多个函数中似乎是成功的。