【问题标题】:AngleSharp error while making the async calls进行异步调用时出现 AngleSharp 错误
【发布时间】:2017-04-14 18:53:57
【问题描述】:

我正在尝试使用AngleSharp 加载许多页面。这个想法是它加载一个页面,如果这个页面有到下一个的链接,加载下一个页面等等,这些方法描述如下。但我得到了内部异常:

Specified argument was out of the range of valid values.
Parameter name: index"

我认为这与Thread 和同步有关。

    public static bool ContainsNextPage(IDocument document)
    {
        String href = document.QuerySelectorAll(".prevnext a")[0].GetAttribute("href");
        if (href == String.Empty)
            return false;
        else
            return true;
    }

    public static string GetNextPageUrl(IDocument document)
    {
        return document.QuerySelectorAll(".prevnext a")[0].GetAttribute("href");

    }

    public static async Task<IDocument> ParseUrlSynch(string Url)
    {
            var config = new Configuration().WithDefaultLoader();
            IDocument document = await BrowsingContext.New(config).OpenAsync(Url);

            return document;
    }

    public static async Task<ConcurrentBag<IDocument>> GetAllPagesDOMs(IDocument initialDocument)
    {

        ConcurrentBag< IDocument> AllPagesDOM = new ConcurrentBag< IDocument>();
        IDocument nextPageDOM;
        IDocument currentDocument = initialDocument;

        if (initialDocument != null)
        {
            AllPagesDOM.Add(initialDocument);
        }

        while (ContainsNextPage(currentDocument))
        {
            String nextPageUrl = GetNextPageUrl(currentDocument);

            nextPageDOM = ParseUrlSynch(nextPageUrl).Result;
            if (nextPageDOM != null)
                AllPagesDOM.Add(nextPageDOM);

            currentDocument = nextPageDOM;
        }

        return AllPagesDOM;
    }

      static void Main(string[] args)
    {



        List<IDocument> allPageDOMs = new List<IDocument>();
        IDocument initialDocument = ParseUrlSynch(InitialUrl).Result;
        List<String> urls = new List<string>();
        List<Subject> subjects = new List<Subject>();
        IHtmlCollection<IElement> subjectAnchors = initialDocument.QuerySelectorAll(".course_title a");

        String[] TitleAndCode;
        String Title;
        String Code;
        String Description;
        IDocument currentDocument = initialDocument;


        ConcurrentBag<IDocument> documents =          

        GetAllPagesDOMs(initialDocument).Result; //Exception in here
        ...
}

【问题讨论】:

    标签: c# .net multithreading asynchronous anglesharp


    【解决方案1】:

    错误信息是由这个代码引起的:

    document.QuerySelectorAll(".prevnext a")[0]
    

    您的一个文档在prevnext 中没有任何锚点。也许它是第一页,也许是最后一页,无论哪种方式,您都需要检查数组的长度。

    此外,阻塞调用异步方法是一种不好的做法,应该避免。您将在任何 UI 应用程序中遇到死锁。你现在没有得到它的唯一原因是你在控制台应用程序中。

    【讨论】:

      【解决方案2】:

      您的直觉是正确的,如果您从具有非默认 SynchronizationContext 的应用程序(例如 WPF、Win Forms 或 ASP.NET)中使用它,那么您将遇到死锁,因为您在 @987654322 上同步阻塞@Task 返回函数(这是不好的,应该避免)。当第一个await 到达阻塞调用内部时,它会尝试将延续发布到当前的SyncronizationContext,它已经被阻塞调用锁定(如果你使用.ConfigureAwait(false),你可以避免这种情况,但是在这种情况下是一个 hack)。

      一个快速的解决方法是通过更改一直使用异步:

      nextPageDOM = ParseUrlSynch(nextPageUrl).Result;
      

      与:

      nextPageDOM = await ParseUrlSynch(nextPageUrl);
      

      在你被这点刺痛了几次之后,你就会学会每次阻塞异步方法时都会在脑海中敲响警钟。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-05-11
        • 2018-02-10
        • 1970-01-01
        • 1970-01-01
        • 2021-07-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多