首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >初始转换后挂起TuesPechkin

初始转换后挂起TuesPechkin
EN

Stack Overflow用户
提问于 2015-01-20 03:55:35
回答 3查看 4.5K关注 0票数 7

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

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

IIS8.5正在Windows 2012 R2上运行。

PDFConversion类在C#中:

代码语言:javascript
复制
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();
        }
    }
}

主计长如下:

代码语言:javascript
复制
    [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。然而,随后的所有帖子都会让Fiddler绞尽脑汁。检查任务管理器显示此任务的CPU和内存分别跳转13.5%和96 up。

在成功运行时,Temp文件夹(存储文件的位置)将包含三个文件:原始上传的文件(以类似GUID的名称存储)、通过wkHtmlToPdf生成的文件(形式为"wktemp-")和生成的pdf (作为tempXXXX.pdf)。在挂起的情况下,只能找到第一个文件,表明问题在wkHtmlToPdf本身的某个地方。

然而,真正的问题是当过程在任务管理器中被手动杀死时,API成功地完成,返回pdf,完全创建!

如果重置IIS,进程将返回原始状态;新尝试将正常工作。

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

这个问题有什么解决办法吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-06-17 11:40:16

很重要-

@toshkata-tonev的答案帮助了我,但是当很多会话使用这个功能时,我们的服务器就崩溃了,因为CPU太多了!

问题是,所有会话都应该将该过程作为静态共享函数共享。

所以这是我的解决办法:

实现:在应用程序中创建一个静态类:

代码语言:javascript
复制
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中,我在项目开始时初始化该类:

代码语言:javascript
复制
TuesPechkinInitializerService.CreateWkhtmltopdfPath();

和使用它:

代码语言:javascript
复制
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

票数 3
EN

Stack Overflow用户

发布于 2015-10-13 15:56:34

编辑:非常重要-这个答案有很多的选票,但不是完整的。检查the marked solution

代码语言:javascript
复制
            var tempFolderDeployment = new TempFolderDeployment();
            var win32EmbeddedDeployment = new Win32EmbeddedDeployment(tempFolderDeployment);
            var remotingToolset = new RemotingToolset<PdfToolset>(win32EmbeddedDeployment);

            var converter =
                 new ThreadSafeConverter(remotingToolset);


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

卸载remotingToolset将防止挂起RemotingToolset.Unload();

票数 15
EN

Stack Overflow用户

发布于 2015-03-24 13:00:59

看起来您使用的是WkHtmlToPdf 64位,您已经安装了32位1位。

你应该改变:

代码语言:javascript
复制
        IConverter converter = new StandardConverter(
            new RemotingToolset<PdfToolset>(
                new Win64EmbeddedDeployment(
                new TempFolderDelpoyment())));

代码语言:javascript
复制
        IConverter converter = new StandardConverter(
            new RemotingToolset<PdfToolset>(
                new Win32EmbeddedDeployment(
                new TempFolderDelpoyment())));
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28037517

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档