htmlAgilityPackのStackoverflow例外を防ぐ方法

c# html-agility-pack stack-overflow

質問

私はMVC 5 Web APIでHtmlAgilityPackを使用しています。時間の99.99%、問題はありません...サイトが読み込まれ、私は私が望むテキストを抽出するためにそれらを解析します。私のAPIは問題なしで1日に数十万回攻撃される可能性があります。過去24時間で200万件以上のヒットを喜んで処理しています...

しかし、ときどきひどく形成されたウェブサイトでは、エラー500が発生します。それ以降のすべての要求に500のエラーが発生し、サイトは完全に使用できなくなります。このシナリオの唯一の解決策は、Webアプリケーションを再起動することです。このサイトはWindows Azureでホストされています。私は負荷バランスのとれたLargeインスタンスを使用していましたが、CPUスパイクは一度高い状態を保ちました。これまで、これは1つのMedium Azureインスタンス(2コア/ 3.5 GB RAM)で正常に動作しましたが、

エラーはStackoverflowです...私は私が捕まえられないことを知っています。

このコードはコンソールアプリケーションをクラッシュさせないことに注意してください

HtmlWeb web = new HtmlWeb();
HtmlDocument doc = web.Load("http://nursingandmidwiferycareersni.com/");            
Console.Write(doc.DocumentNode.InnerText);

...それは間違いなくMVCのWebアプリケーションをクラッシュさせます。

しかし、単純なMVC Webアプリケーションでは、 http://nursingandmidwiferycareersni.com/のようなサイトでstackoverflowエラーを再現することができます。 http://nursingandmidwiferycareersni.com/https://validator.w3.orgに入れると、validator.w3.orgで内部サーバーエラーが発生します。

これを回避するために必要ならHAPソースコードをハックします...現在、私はちょうどNugetパッケージを使用しています。

HAPで起こっているstackoverflowを防ぐことは可能ですか?
または、ひどいhtmlをチェックし、最初にクラッシュが発生するのを防ぐ方法がありますか?

人気のある回答

ParseHtmlメソッドとParsedHtmlタイプは、入力するだけのプレースホルダです。

public async Task<ParsedHtml> TryParseHtml(
    string untrustedHtml,
    CancellationToken cancellationToken)
{
    var tcs = new TaskCompletionSource<ParsedHtml>();

    var thread = new Thread(() =>
    {
        ParsedHtml result = ParseHtml(untrustedHtml);
        tcs.TrySetResult(result);
    });
    thread.Start();

    using (cancellationToken.Register(() => tcs.TrySetCanceled()))
    {
        try
        {
            return await tcs.Task;
        }
        catch (OperationCanceledException)
        {
            thread.Abort();
            throw;
        }
    }
}

このアイデアは、すべてのHTMLページのスレッドを起動して破棄するのではなく、成功したケースでスレッドを再利用することで、より効率的に拡張できます。



Related

ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow