简体   繁体   中英

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. 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. 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. 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. 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.

at the very top of getNews try this:

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);

Of course, doing it this way effectively marshalls your getNews to the UI thread. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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