【问题标题】:String remains null even after putting data即使放入数据后字符串仍然为空
【发布时间】:2014-03-20 20:09:45
【问题描述】:

我是 Windows Metro 应用程序的新手,完全被困在这里。 textbox1.text 在函数内部显示准确的数据,但 Aya 在函数外部保持为空。我怎么解决这个问题 ?我认为递归正在造成问题,但如何解决呢?

public async void Aya_Parse()
    {

        // Initialize http client.
        HttpClient httpClient = new HttpClient();
        Stream stream = await httpClient.GetStreamAsync("some link");

        // Load html document from stream provided by http client.
        HtmlDocument htmlDocument = new HtmlDocument();
        htmlDocument.OptionFixNestedTags = true;
        htmlDocument.Load(stream);

        Aya_ParseHtmlNode(htmlDocument.DocumentNode);
    }

    int aia = 0;
    string Aya = null;
    private void Aya_ParseHtmlNode(HtmlNode htmlNode)
    {

        foreach (HtmlNode childNode in htmlNode.ChildNodes)
        {


            if (childNode.NodeType == HtmlNodeType.Text && aia == 1)
            {

                Aya += " " + childNode.InnerText.ToString(); aia = 0;

            }

            else if (childNode.NodeType == HtmlNodeType.Element)
            {
               Aya += " "; // removing this causes null exception at textbox1.text 

                switch (childNode.Name.ToLower())
                {

                    case "span":
                        Aya += childNode.NextSibling.InnerText.ToString();

                       Aya_ParseHtmlNode(childNode);
                        break;
                    case "td":

                        aia = 1;
                        Aya_ParseHtmlNode(childNode);break;

                    default:

                        Aya_ParseHtmlNode(childNode); break;
                }
            }
        }
        textBox1.Text = Aya;

    }

【问题讨论】:

    标签: c# microsoft-metro html-parsing html-agility-pack


    【解决方案1】:

    您永远不会为Aya 分配起始值,因此即使您尝试在Aya_ParseHtmlNode(HtmlNode htmlNode) 方法中向其添加文本,也无法将文本添加到空值。这可以通过检查 null 的值并将其设置为默认值来解决。我很惊讶您的方法中没有 NullArgumentException...

    public async void Aya_Parse()
    {
    
        // Initialize http client.
        HttpClient httpClient = new HttpClient();
        Stream stream = await httpClient.GetStreamAsync("some link");
    
        // Load html document from stream provided by http client.
        HtmlDocument htmlDocument = new HtmlDocument();
        htmlDocument.OptionFixNestedTags = true;
        htmlDocument.Load(stream);
        //  greetingOutput.Text = htmlDocument.DocumentNode.InnerText.ToString();
        // Parse html node, this is a recursive function which call itself until
        // all the childs of html document has been navigated and parsed.
        Aya_ParseHtmlNode(htmlDocument.DocumentNode);
    }
    
    int aia = 0;
    string Aya = null;
    private void Aya_ParseHtmlNode(HtmlNode htmlNode)
    {
        if (Aya == null)
        {
            Aya = String.empty;
        }
        foreach (HtmlNode childNode in htmlNode.ChildNodes)
        {
    
    
            if (childNode.NodeType == HtmlNodeType.Text && aia == 1)
            {
    
                Aya += " " + childNode.InnerText.ToString(); aia = 0;
    
            }
    
            else if (childNode.NodeType == HtmlNodeType.Element)
            {
               Aya += " ";
    
                switch (childNode.Name.ToLower())
                {
    
                    case "span":
                        Aya += childNode.NextSibling.InnerText.ToString();
    
                       Aya_ParseHtmlNode(childNode);
                        break;
                    case "td":
    
                        aia = 1;
                        Aya_ParseHtmlNode(childNode);break;
    
                    default:
    
                        Aya_ParseHtmlNode(childNode); break;
                }
            }
        }
        textBox1.Text = Aya;
    
    }
    

    在这里使用StringBuilder 也可能是一个更好的主意,因为您可以在这里递归并生成一个非常 大的字符串,所以StringBuilder 会更容易记忆

    public void Aya_Parse()
    {
    
        // Initialize http client.
        HttpClient httpClient = new HttpClient();
        Stream stream =  httpClient.GetStreamAsync("some link").Result;
    
        // Load html document from stream provided by http client.
        HtmlDocument htmlDocument = new HtmlDocument();
        htmlDocument.OptionFixNestedTags = true;
        htmlDocument.Load(stream);
        //  greetingOutput.Text = htmlDocument.DocumentNode.InnerText.ToString();
        // Parse html node, this is a recursive function which call itself until
        // all the childs of html document has been navigated and parsed.
    
    
        //you marked the method Async, and
        //since Aya is in the class, if multiple threads call this
        //method, you could get inconsistent results
        //I have changed it to a parameter here so this doesn't happen
        StringBuilder Aya = new StringBuilder()
        Aya_ParseHtmlNode(htmlDocument.DocumentNode, Aya);
        //I would also move your textbox update here, so you aren't calling
        //ToString() all the time, wasting all of the memory benefits
        textBox1.Text = Aya.ToString();
    }
    
    int aia = 0;
    private void Aya_ParseHtmlNode(HtmlNode htmlNode, StringBuilder Aya)
    {
    
        foreach (HtmlNode childNode in htmlNode.ChildNodes)
        {
    
    
            if (childNode.NodeType == HtmlNodeType.Text && aia == 1)
            {
    
                Aya.Append(childNode.InnerText); aia = 0;
    
            }
    
            else if (childNode.NodeType == HtmlNodeType.Element)
            {
               Aya.Append(" ");
    
                switch (childNode.Name.ToLower())
                {
    
                    case "span":
                        Aya.Append(childNode.NextSibling.InnerText);
    
                       Aya_ParseHtmlNode(childNode, Aya);
                        break;
                    case "td":
    
                        aia = 1;
                        Aya_ParseHtmlNode(childNode, Aya);break;
    
                    default:
    
                        Aya_ParseHtmlNode(childNode, Aya); break;
                }
            }
        }
    }
    

    编辑:您的问题实际上可能来自您在Aya_Parse() 上使用了async 关键字,这意味着调用Aya_Parse() 的方法可能会在之前返回立即它实际上做了任何处理。因此,如果您在调用Aya_Parse() 之后检查Aya 的值,那么在您实际检查代码中其他地方的值之前,它可能没有足够的时间进行计算。我建议删除async 标记,或更改Aya_Parse() 以在完成时返回Aya 的值。查看here 了解如何使用async 标记返回值。

    【讨论】:

      【解决方案2】:

      可能是这样。它的行为就好像你的字符串变量是按值传递给方法的,而不是持有引用。

      请记住,通过使用异步方法,您实际上是多线程,因此多个线程将争夺同一个模块级变量。编译器可能会选择让您的代码对您来说是线程安全的。

      如果您在异步方法中声明一个单独的字符串并通过 ref 将其传递,则其行为应该符合您的预期。

      我还建议您对模块级别的 int 执行相同的操作。

      或者...您可以从 Aya_Parse 中删除异步并使用任务库(并在下面的等待调用中折腾)来获取您的流。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-05
        • 2015-08-04
        • 2021-06-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多