简体   繁体   English

具有线程的C#RSS feed阅读器,将feed多次写入listView

[英]C# RSS feed reader with thread, feeds are written to listView multiple times

I have a RSS news reader which reads a rss feed and writes the news with links in a ListView. 我有一个RSS新闻阅读器,它可以读取rss提要,并在ListView中使用链接写入新闻。 when I'm executing my program I'm starting a new thread like this: 当我执行程序时,我正在启动一个新线程,如下所示:

    Thread myThread = new Thread(getNews);
    myThread.Start();

My method to read the feed looks like this: 我读取提要的方法如下所示:

    public void getNews()
    {  
        //Creates a XmlTextReader which reads from the url entered in input field
        rssReader = new XmlTextReader(txtUrl.Text);

        //Creates an xml doc to save the content of the entered path
        rssDoc = new XmlDocument();

        //Loads the xml content from the reader into a XmlDocument
        rssDoc.Load(rssReader);

        //Make a loop to search for the <rss> tag
        for (int i = 0; i < rssDoc.ChildNodes.Count; i++)
        {
            //If the childenode is the rss tag
            if (rssDoc.ChildNodes[i].Name == "rss")
            {
                //the <rss> tag is found, and we know where it is
                nodeRss = rssDoc.ChildNodes[i];
            }
        }

        //Make a loop to search for the <channel> tag
        for (int i = 0; i < nodeRss.ChildNodes.Count; i++)
        {
            //If the childnode is the channel tag
            if (nodeRss.ChildNodes[i].Name == "channel")
            {
                //The channel tag is found and we know where it is
                nodeChannel = nodeRss.ChildNodes[i];
            }
        }

        //Make a loop to search for the <item> tag
        for (int i = 0; i < nodeChannel.ChildNodes.Count; i++)
        {
            //If the childnode is the item tag
            if (nodeChannel.ChildNodes[i].Name == "item")
            {
                //the item tag is found, and we know where it is
                nodeItem = nodeChannel.ChildNodes[i];

                //Creates a new row in the LstView which contains information from inside the nodes
                rowNews = new ListViewItem();
                rowNews.Text = nodeItem["title"].InnerText;
                rowNews.SubItems.Add(nodeItem["link"].InnerText);

                if (this.lstView.InvokeRequired)
                {
                    AddItemCallback d = new AddItemCallback(getNews);
                    this.Invoke(d);
                }
                else
                {
                    lstView.Items.Add(rowNews);
                }
            }

        }

My problem is, after I started to run my code in a new thread and use the delegate to check if the listView requres an invoked all the news feeds are written in my listView mulitple times. 我的问题是,在我开始在新线程中运行代码并使用委托后,检查listView是否要求被调用的所有新闻提要多次写入我的listView中。 if I run method without starting a new thread and using the delegate its only written once, why is that? 如果我在不启动新线程的情况下运行方法并且仅使用委托编写一次该委托,那为什么呢? It's probably a very simple question but just can't seeme to figure out why 这可能是一个非常简单的问题,但无法找出原因

Thanks in advance, code examples are appreciated :) 在此先感谢,感谢代码示例:)

If invoke is required, you're calling the getNews method again. 如果需要invoke,那么您将再次调用getNews方法。 Instead of using this code: 而不是使用此代码:

if (this.lstView.InvokeRequired)
{
     AddItemCallback d = new AddItemCallback(getNews); // STOP CALLING getNews
     this.Invoke(d);
}

You need to call another method to update your UI. 您需要调用另一种方法来更新您的UI。 It's a giant loop. 这是一个巨大的循环。

You put your invocation check in the wrong place - thus your getNews function is being called many many more times than you intended. 您将调用检查放在错误的位置–因此,调用getNews函数的次数比预期的要多得多。

at the very top of getNews try this: 在getNews的顶部尝试以下操作:

if (this.lstView.InvokeRequired) {
AddItemCallback d = new AddItemCallback(getNews);
this.Invoke(d);
return;
}

Then replace the if statement at the end with lstView.Items.Add(rowNews); 然后在末尾将if语句替换为lstView.Items.Add(rowNews);

Of course, doing it this way effectively marshalls your getNews to the UI thread. 当然,通过这种方式可以有效地将getNews编组到UI线程。 What you really need is to build a collection of ListViewItems and pass that collection to an Updater method.. and in THAT method you check if invokation is required. 您真正需要的是构建ListViewItems的集合并将该集合传递给Updater方法。在该方法中,您检查是否需要调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM