初始转换后悬挂TuesPechkin [英] Hanging TuesPechkin after initial conversion

查看:85
本文介绍了初始转换后悬挂TuesPechkin的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个Web API,该API可以将样式化的HTML文件转换为PDF.

I am attempting to create a Web API that can convert a styled HTML file into a PDF.

我正在使用TuesPechkin,并将我的应用程序安装到IIS中(作为32位应用程序:我已经修改了应用程序池以在32位模式下运行).

I am using TuesPechkin and have installed my application into IIS (as a 32-bit app: I have modified the application pool to run in 32bit mode).

IIS 8.5在Windows Server 2012 R2上运行.

IIS 8.5 is running on Windows Server 2012 R2.

C#中的PDFConversion类:

PDFConversion class in C#:

using System.Drawing.Printing;
using System.IO;
using TuesPechkin;

namespace PDFApi
{
    public class PDFcreator
    {
        public void convert(string path, string uri)
        {
            IConverter converter = new StandardConverter(
                new RemotingToolset<PdfToolset>(
                    new Win64EmbeddedDeployment(
                    new TempFolderDelpoyment())));

            var document = new HtmlToPdfDocument
            {
                GlobalSettings =
                {
                    ProduceOutline = true,
                    DocumentTitle = "Converted Form",
                    PaperSize = PaperKind.A4,
                    Margins =
                    {
                        All = 1.375,
                        Unit = Unit.Centimeters
                    }
                },
                Objects =
                {
                    new ObjectSettings { RawData = File.ReadAllBytes(uri) }
                }
            };

            byte[] pdfBuf = converter.Convert(document);

            FileStream fs = new FileStream(path, FileMode.Create);
            fs.Write(pdfBuf, 0, pdfBuf.Length);
            fs.Close();
        }
    }
}

控制器如下:

    [Route("converthtml")]
    [HttpPost]
    [MIMEContentFilter]
    public async Task<HttpResponseMessage> ConvertHtml()
    {
        string temppath = System.IO.Path.GetTempPath();

        var streamProvider = new MultipartFormDataStreamProvider(temppath);
        await Request.Content.ReadAsMultipartAsync(streamProvider);


        string filepath = streamProvider.FileData.Select(entry => entry.LocalFileName.Replace(temppath + "\\", "")).First<string>();
        string pdfpath = System.IO.Path.GetTempFileName();
        pdfpath = pdfpath.Substring(0, pdfpath.LastIndexOf('.')) + ".pdf";

        new PDFcreator().convert(pdfpath, filepath);

        var stream = new FileStream(pdfpath, FileMode.Open);
        var result = new HttpResponseMessage(HttpStatusCode.OK);
        result.Content = new StreamContent(stream);
        result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
        return result;
    }

有点奇怪:在Fiddler中进行实验,发送一次文件将立即返回PDF.但是,所有后续的POST将使Fiddler挂起.检查任务管理器显示此任务的CPU和内存分别跳至13.5%和〜96MB.

Here's where it gets a little odd: Experimenting in Fiddler, sending a file once will return the PDF immediately. However, all subsequent POSTs will leave Fiddler hanging. Examining Task Manager shows the CPU and Memory for this task to jump up to 13.5% and ~96MB respectively.

Temp文件夹(用于存储文件)在成功运行后将包含三个文件:原始上载的文件(以类似GUID的名称存储),通过wkHtmlToPdf生成的文件(格式为"wktemp-)和生成的pdf(作为tempXXXX.pdf).如果挂起,则只能找到第一个文件,这表明问题出在wkHtmlToPdf本身中.

The Temp folder (where the files are stored), on a successful run, will have three files in it: the original uploaded file (stored with a GUID-like name), the file generated via wkHtmlToPdf (in the form "wktemp-"), and the generated pdf (as tempXXXX.pdf). In the case of it hanging, only the first file can be found, indicating that the problem is somewhere in wkHtmlToPdf itself.

但是,真正的关键是当在Task Manager中手动终止进程时,API成功完成,返回完全创建的pdf!

However, the real kicker is when the process is manually killed in Task Manager, the API completes successfully, returns the pdf, fully created!

如果IIS被重置,则该过程返回到原始状态;否则,该过程将恢复为原始状态.一次新尝试将毫无问题.

If IIS is reset, the process returns to the original state; a new attempt will work without issue.

显然,在每次调用后重置IIS几乎是不可行的,也不是每次都手动终止该进程...

Obviously, resetting IIS after every call is hardly viable, nor is manually killing the process each time...

这是一个错误/对此问题有任何解决方案吗?

Is this a bug / are there any solutions to this issue?

推荐答案

非常重要-

@ toshkata-tonev答案对我有所帮助,但是当许多会话使用此功能时,由于CPU过多,我们的服务器崩溃了!

@toshkata-tonev answer helped me, but when a lot of sessions used this function our server crushed because over CPU!

重点是该过程应作为静态共享功能由所有会话共享.

The point is that the process should be shared by all sessions as static shared function.

这就是我的解决方案:

实施:在您的应用程序中创建一个静态类:

public static class TuesPechkinInitializerService {
    private static string staticDeploymentPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "wkhtmltopdf");

public static void CreateWkhtmltopdfPath()
    {
        if (Directory.Exists(staticDeploymentPath) == false)
        {
            Directory.CreateDirectory(staticDeploymentPath);
        }
    }

    public static IConverter converter = 
        new ThreadSafeConverter(
            new RemotingToolset<PdfToolset>(
                new Win64EmbeddedDeployment(
                    new StaticDeployment(staticDeploymentPath)
                )
            )
        );
}

在GLOBAL.asax中,我在项目开始时初始化该类:

TuesPechkinInitializerService.CreateWkhtmltopdfPath();

并使用它:

HtmlToPdfDocument pdfDocument = new HtmlToPdfDocument
                {
                    GlobalSettings = new GlobalSettings(),
                    Objects =
                    {
                        new ObjectSettings
                        { 
                            ProduceLocalLinks = true,
                            ProduceForms = true,
                            HtmlText = htmlContent
                        }                    
                    }
                };

                byte[] pdfDocumentData = TuesPechkinInitializerService.converter.Convert(pdfDocument);

感谢:

https://github.com/tuespetre/TuesPechkin/issues/152

这篇关于初始转换后悬挂TuesPechkin的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆