使用GetByteArrayAsync在C#中解析HTML很困难

时间:2015-08-17 21:24:42

标签: c# html

    public BarchartParser()
    {
        // Initialize list
        StockSymbols = new List<string>();

        // Add items
        ParseBarchart();
    }

这是调用方法

的C&C。来源
    private async void ParseBarchart()
    {
        try
        {
            #region Get Html Document

            // Get response from site
            HttpClient http = new HttpClient();
            var response = await http.GetByteArrayAsync(BARCHART_WEBSITE);
            /* Break or W/e happens on this line ^^^ */

            // Encode html response to UTF-8
            string source = Encoding.GetEncoding(BARCHART_ENCODING)
                                        .GetString(response, 0, response.Length - 1);

            // Get html
            HtmlDocument document = new HtmlDocument();
            document.LoadHtml(source);

            #endregion

            #region Get Data From Table

            // Get table containining stock info
            HtmlNode table = document.DocumentNode.Descendants()
                .Single<HtmlNode>
            (
                x => (x.Name == "table") &&
                     (x.Attributes["class"] != null) &&
                     (x.Attributes["class"].Value.Equals("datatable ajax")) &&
                     (x.Attributes["id"].Value.Equals("dt1"))
            );

            // Get 'tbody' element from table
            HtmlNode tbody = table.Descendants("tbody").FirstOrDefault();

            // Get all rows from the table
            List<HtmlNode> allStocks = tbody.Descendants("tr").ToList();

            // For each row, id is "td1_X" where X is the symbol of the stock
            foreach (HtmlNode row in allStocks)
            {
                StockSymbols.Add(row.Attributes["id"].Value.ToString()
                    .Split(new char[] { '_' })[1]);
            }

            #endregion
        }
        catch
        {
            StockSymbols = new List<string>();
            StockSymbols.Add("this didn't work");
        }
    }

来自使用它的简单表单应用程序的代码:

    BarchartParser barchartData;

    public Form1()
    {
        InitializeComponent();
        barchartData = new BarchartParser();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        if (barchartData.StockSymbols != null && barchartData.StockSymbols.Count > 0)
            MessageBox.Show(barchartData.StockSymbols[0]);
        else
            MessageBox.Show("barchartData.StockSymbols is null or count == 0");
        this.Close();
    }

不完全确定这里发生了什么。它调试了一次,然后停止工作 此代码是在C&C期间调用的函数的一部分。当这个投掷或其他任何事情发生时,
它只是继续到我在调试模式下设置的下一个断点...任何人都知道什么是什么 可能是这个原因?

编辑:我知道它不是一个抛出,因为catch块中的代码不会发生。它只是继续前进

总的来说,我遵循本指南https://code.msdn.microsoft.com/Parsing-Html-using-C-721be358/sourcecode?fileId=122353&pathId=1834557721

2 个答案:

答案 0 :(得分:0)

当await语句抛出异常时,只有try块可以捕获它。我建议你添加一个try-catch或try-finally来捕获异常并正确处理它。

答案 1 :(得分:0)

您不是await - async方法,因此只有方法的同步部分(基本上是第一个真实await)将作为构造函数调用的一部分执行,其余部分最终会在一些任意的情况下运行(如果发生异常,可能会导致进程停止)。

通常,如果您尝试调用.Result.Wait()await vs Task.Wait - Deadlock?),则无法从构造函数调用异步方法,而不会出现死锁的可能性。作为选项,您可以查看Fire-and-forget with async vs "old async delegate"是否适合您的情况。

正确的修复方法是将异步操作从同步方法(如构造函数)移动到显式异步方法并相应地调用它。

Hacky修复(使用likley死锁):

public BarchartParser()
{   
    ...
    ParseBarchart().Wait();
}