请求在 .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();          
}

请求在 .NET MVC 4 中过早终止,可能是由于多线程工作

找到了。等待句柄必须小于或等于 64。

有关解决方案,请参阅 WaitHandle.WaitAll 64 句柄限制的 http://www.codeproject.com/Articles/142341/Solved-The-number-of-WaitHandles-must-be-less-than 或解决方法?