我正在尝试在我的 MVC 应用程序中生成特定表单的 PDF 副本。由于这很耗时,并且客户端不需要等待这一代发生,我试图将其作为一系列 Fire and Forget Tasks 来触发。
需要注意的一个问题是我需要建立 HttpContext,否则一些我无法更改的底层代码将不起作用。我相信我已经解决了这个问题,但我想把它说出来以防万一。
这是我正在调用的函数...
private void AsyncPDFFormGeneration(string htmlOutput, string serverRelativePath, string serverURL, string signature, ScannedDocument document, HttpContext httpContext)
{
try
{
System.Web.HttpContext.Current = httpContext;
using (StreamWriter stw = new StreamWriter(Server.MapPath(serverRelativePath), false, System.Text.Encoding.Default))
{
stw.Write(htmlOutput);
}
Doc ABCDoc = new Doc();
ABCDoc.HtmlOptions.Engine = EngineType.Gecko;
int DocID = 0;
DocID = ABCDoc.AddImageUrl(serverURL + serverRelativePath + "?dumb=" + DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second + DateTime.Now.Millisecond);
while (true)
{
ABCDoc.FrameRect();
if (!ABCDoc.Chainable(DocID))
break;
ABCDoc.TextStyle.LeftMargin = 100;
ABCDoc.Page = ABCDoc.AddPage();
DocID = ABCDoc.AddImageToChain(DocID);
}//End while (true...
for (int i = 1; i <= ABCDoc.PageCount; i++)
{
ABCDoc.PageNumber = i;
ABCDoc.Flatten();
}
ScannedDocuments.AddScannedDocument(document, ABCDoc.GetData());
System.IO.File.Delete(Server.MapPath(serverRelativePath));
}
catch (Exception e)
{
//Exception is logged to the database, and if that fails, to the Event Log
}
}
在其中,我将相关 MVC 表单的 HTML 内容的字符串输出写入 html 文件,将该文件的路径交给 PDF 编写器,生成 PDF,然后删除 html 文件。
我在 Controller POST 方法中调用它,如下所示:
Task.Run(() => AsyncPDFFormGeneration(htmlOutput, serverRelativePath,
serverURL, signature, document, HttpContext.ApplicationInstance.Context));
该命令被称为 foreach 循环的一部分,该循环构造表单,将它们加载为字符串格式,然后将它们传递给任务。我也试过这个
Task.Factory.StartNew
以防万一Task.Run发生了一些奇怪的事情,但这并没有产生不同的结果。
我遇到的问题是并非所有任务每次都执行。如果我在 Visual Studio 中运行并逐步调试,它每次都能正常工作。但是,当尝试顺序生成 11 个表单时,有时会生成所有表单,有时会生成 3 或 4 个,有时会生成除 1 之外的所有表单。
我将错误日志设置为尽可能广泛,但没有抛出我能找到的异常,并且由于线程中途中止,我的文件结构中没有留下任何生成的 html 文件。
页面从帖子返回的速度与生成的表单数量之间似乎存在轻微的相关性。较长的加载时间通常与生成的更多表单相关......但我的印象应该是无关紧要的。我将它们分离出来,将线程与它们自己的 HttpContext 副本分开,以便随身携带。一旦启动,我认为原始线程不会影响它们。
关于为什么我在某些尝试中只获得 3 个成功的任务,在另一次尝试中全部 11 个,并且没有例外的任何想法?