请求在 .NET MVC 4 中过早终止,可能是由于多线程工作
本文关键字:工作 多线程 终止 MVC NET 请求 | 更新日期: 2023-09-27 17:55:39
在操作方法中,我尝试为每个合约生成单独的报告,压缩所有报告并将zip文件发送回客户端。
为了提高性能,我使用 ThreadPool.QueueUserWorkItem 方法来多线程处理任务。若要在发送回 zip 文件之前等待所有工作完成,此处使用 WaitHandle.WaitAll 方法。
它适用于小型数据集。例如,一个 9 合约数据集的整个过程需要 1.5 分钟。 但是对于具有 86 个合约的大型数据集,响应会在我发送请求后立即返回。这是一个无效的 zip 文件。我可以告诉线程仍在运行以生成报告。但是据我所知,WaitHandle.WaitAll和之后的任何内容都没有被执行。
知道为什么吗?
public void GenerateReport(ReportParams parameters)
{
System.Web.HttpContext.Current.Response.Clear();
System.Web.HttpContext.Current.Response.BufferOutput = false; // for large files
System.Web.HttpContext.Current.Response.ContentType = "application/zip";
const string filename = "test.zip";
System.Web.HttpContext.Current.Response.AddHeader("content-disposition", "filename=" + filename);
ThreadPool.SetMaxThreads(4, 4);
Log.Info("Starting the batch report");
using (var zip = new ZipFile())
{
var doneEvents = new ManualResetEvent[parameters.Contracts.Length];
for (int i = 0; i < parameters.Contracts.Length; i++)
{
var contract = parameters.Contracts[i];
doneEvents[i] = new ManualResetEvent(false);
ThreadPool.QueueUserWorkItem(
ExportReport,
new ThreadInfo
{
Contract = contract,
Zip = zip,
DoneEvent = doneEvents[i]
});
}
WaitHandle.WaitAll(doneEvents);
zip.Save(System.Web.HttpContext.Current.Response.OutputStream);
}
Log.Info("Finishing the batch report");
}
protected void ExportReport(object obj)
{
var info = obj as ThreadInfo;
var reportDoc = new ReportDocument();
Log.Info("Thread Id {0} processing contract {1}", Thread.CurrentThread.ManagedThreadId, info.Contract);
SetPath(reportDoc);
SetDbInfo(reportDoc);
LoadParameter(reportDoc);
reportDoc.SetParameterValue("Contract", info.Contract);
reportDoc.ExportToDisk(
ExportFormatType.PortableDocFormat,
string.Format(@"C:'TempFile'{0}.pdf", info.Contract));
info.Zip.AddFile(string.Format(@"C:'TempFile'{0}.pdf", info.Contract));
Log.Info("Thread Id {0} finishing contract {1}", Thread.CurrentThread.ManagedThreadId, info.Contract);
reportDoc.Dispose();
info.DoneEvent.Set();
}
找到了。等待句柄必须小于或等于 64。
有关解决方案,请参阅 WaitHandle.WaitAll 64 句柄限制的 http://www.codeproject.com/Articles/142341/Solved-The-number-of-WaitHandles-must-be-less-than 或解决方法?