0

分離されたアプリケーションプール(ApplicationPoolIdentity)を備えたクラシックASPでIIS7.5を使用してWebサイトを実行しています。このWebサイト内では、「WScript.Shell」オブジェクト実行メソッドを介してアンマネージコード(wkhtmltopdf.exe)も実行しています。その後、結果ファイルをpdfとしてストリーミングします

set wshell = CreateObject("WScript.Shell") 
wshell.run wkhtmltopdf.exe  http://www.mypagehanging.com c:\myfile.pdf", 0, TRUE 
set wshell = nothing 

すべて正常に動作しますが、時々私のWebサイトがハングします。完全に動かなくなっています。アプリプール(iis apppool \ myapp)のIDで実行されているwktmltopdf.exeがハングします。

これにより、オプションbWaitOnReturnをtrueに設定してプログラムを実行するため、すべてのWebサイトがハングします。

PDFをストリーミングする前にスクリプトが完全に実行されるのを待つ必要があるため、このオプションをfalseに設定することはできません。

wkhtmltopdfに与えるタイムアウトオプションが見つかりませんでした。wkhtmltopdfがぶら下がっている理由がわかりませんでした。しかし、それはおそらく、wkhtmltopdfではなく、レンダリングしようとしているWebサイトが原因です。

助言がありますか ?

4

1 に答える 1

0

実行に異常な時間がかかる場合は、プロセスを強制終了することで、この問題に対処しました。

これが私のコードです。誰かに役立つはずです。

aspファイル内

'Run this programm that will kill pdf generation if it hangs-execute for more than 10seconds
wshell.run "KillProcess.exe -p wkhtmltopdf -t 10000",0,FALSE 
'Launch pdf generation with bwaitonreturn true 
wshell.run wkhtmltopdf.exe  http://www.mypagehanging.com  c:\inetpub\wwwroot\myfile.pdf", 0, TRUE 

'Stream the pdf ...

KillProcess.exeのコードソース

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;
using CommandLine; //http://commandline.codeplex.com
using CommandLine.Text; //http://commandline.codeplex.com

namespace KillProcess
{
    class Program
    {
        static void Main(string[] args)
        {
            var options = new Options();
            ICommandLineParser parser = new CommandLineParser();

            if (parser.ParseArguments(args, options))
            {
                double maxWaitTime = options.time; //ms
                string processName = options.process;
                bool exit;
                do
                {
                    exit = true;
                    foreach (Process p in GetProcesses(processName))
                    {
                        exit = false;
                        try
                        {
                            if (p.StartTime.AddMilliseconds(maxWaitTime) < DateTime.Now)
                            {
                                p.Kill();
                                Console.WriteLine("Killed Process: {0} ID: {1} started at {2} after {3}ms of execution time", p.ProcessName, p.Id, p.StartTime, options.time);
                            }
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(e.Message);
                        }
                    }
                    Thread.Sleep(100);
                } while (!exit);
                return;
            }
            else
            {
                Console.WriteLine(options.GetUsage());
                return;
            }
        }

        static IEnumerable<Process> GetProcesses(string processName)
        {
            var processes = from p in Process.GetProcesses()
                            where p.ProcessName == processName
                            orderby p.ProcessName
                            select p;
            return processes;
        }

        class Options : CommandLineOptionsBase
        {
            [Option("p", "process", Required = true, HelpText = "Name of the process-es to kill after some execution time (Warning ! This will kill all the processes that match the name !)")]
            public string process { get; set; }

            [Option("t", "time", Required = true, HelpText = "Maximum execution time allowed for the process to run. If the process has run for more than this amount of time it will be killed")]
            public int time { get; set; }

            [HelpOption]
            public string GetUsage()
            {
                return HelpText.AutoBuild(this, (HelpText current) => HelpText.DefaultParsingErrorsHandler(this, current));
            }
        }
    }
}
于 2012-08-08T09:43:55.000 に答える