Comment expirer une requête en utilisant Html Agility Pack

.net asp.net-mvc-3 c# html-agility-pack timeout

Question

Je fais une demande à un serveur Web distant actuellement hors ligne (volontairement).

Je voudrais trouver le meilleur moyen de temporiser la demande. Fondamentalement, si la demande dure plus de "X" millisecondes, quittez la demande et renvoyez une réponse null .

Actuellement, la requête Web attend juste une réponse .....

Comment pourrais-je mieux aborder ce problème?

Voici un extrait de code actuel

    public JsonpResult About(string HomePageUrl)
    {
        Models.Pocos.About about = null;
        if (HomePageUrl.RemoteFileExists())
        {
            // Using the Html Agility Pack, we want to extract only the
            // appropriate data from the remote page.
            HtmlWeb hw = new HtmlWeb();
            HtmlDocument doc = hw.Load(HomePageUrl);
            HtmlNode node = doc.DocumentNode.SelectSingleNode("//div[@class='wrapper1-border']");

            if (node != null)
            { 
                about = new Models.Pocos.About { html = node.InnerHtml };
            }
                //todo: look into whether this else statement is necessary
            else 
            {
                about = null;
            }
        }

        return this.Jsonp(about);
    }

Réponse acceptée

J'ai dû faire un petit ajustement à mon code posté d'origine

    public JsonpResult About(string HomePageUrl)
    {
        Models.Pocos.About about = null;
        // ************* CHANGE HERE - added "timeout in milliseconds" to RemoteFileExists extension method.
        if (HomePageUrl.RemoteFileExists(1000))
        {
            // Using the Html Agility Pack, we want to extract only the
            // appropriate data from the remote page.
            HtmlWeb hw = new HtmlWeb();
            HtmlDocument doc = hw.Load(HomePageUrl);
            HtmlNode node = doc.DocumentNode.SelectSingleNode("//div[@class='wrapper1-border']");

            if (node != null)
            { 
                about = new Models.Pocos.About { html = node.InnerHtml };
            }
                //todo: look into whether this else statement is necessary
            else 
            {
                about = null;
            }
        }

        return this.Jsonp(about);
    }

Puis j'ai modifié ma méthode d'extension RemoteFileExists pour avoir un délai d'attente

    public static bool RemoteFileExists(this string url, int timeout)
    {
        try
        {
            //Creating the HttpWebRequest
            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;

            // ************ ADDED HERE
            // timeout the request after x milliseconds
            request.Timeout = timeout;
            // ************

            //Setting the Request method HEAD, you can also use GET too.
            request.Method = "HEAD";
            //Getting the Web Response.
            HttpWebResponse response = request.GetResponse() as HttpWebResponse;
            //Returns TRUE if the Status code == 200
            return (response.StatusCode == HttpStatusCode.OK);
        }
        catch
        {
            //Any exception will returns false.
            return false;
        }
    }

Dans cette approche, si mes feux de temporisation avant RemoteFileExists peut déterminer la réponse d' en- tête, alors mon bool retournera false.


Réponse populaire

Html Agility Pack est une solution ouverte. C'est pourquoi vous pouvez modifier la source vous-même. Pour d’abord, ajoutez ce code à la classe HtmlWeb :

private int _timeout = 20000;

public int Timeout 
    { 
        get { return _timeout; } 
        set
        {
            if (_timeout < 1) 
                throw new ArgumentException("Timeout must be greater then zero.");
            _timeout = value;
        }
    }

Alors trouve cette méthode

private HttpStatusCode Get(Uri uri, string method, string path, HtmlDocument doc, IWebProxy proxy, ICredentials creds)

et le modifier:

req = WebRequest.Create(uri) as HttpWebRequest;
req.Method = method;
req.UserAgent = UserAgent;
req.Timeout = Timeout; //add this

Ou quelque chose comme ça:

htmlWeb.PreRequest = request =>
            {
                request.Timeout = 15000;
                return true;
            };


Related

Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow