RSS Reader несколько потоков C # - PullRequest
1 голос
/ 08 апреля 2011

Я хочу создать программу для чтения RSS, которая позволяет получать несколько новостных лент одновременно, без «зависания» моего приложения при получении канала. Чтобы сделать это, я хочу, чтобы часть кода выполнялась в отдельном потоке. Я пробовал разные вещи, чтобы заставить его работать в отдельном потоке, но я продолжаю получать исключения. Мой код выглядит следующим образом:

namespace NewsReader
{
    public partial class Form1 : Form
    {
        XmlTextReader rssReader;

        XmlDocument rssDoc;

        XmlNode nodeRss;

        XmlNode nodeChannel;

        XmlNode nodeItem;

        ListViewItem rowNews;

        public Form1()
        {
            InitializeComponent();
        }

        private void btnRead_Click(object sender, EventArgs e)
        {

            //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);
                    lstView.Items.Add(rowNews);

                }
            }

        }
    }

}

У кого-нибудь есть примеры, как справиться с этой проблемой? Примеры кода с моим кодом очень ценится:)

Заранее спасибо.

Ответы [ 3 ]

2 голосов
/ 08 апреля 2011

Вы можете оформить BackgroundWorker класс. И вот пример:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
using System.Xml.Linq;
using System.Xml.XPath;

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        backgroundWorker1.RunWorkerAsync(txtUrl.Text);
    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        var rssDoc = XDocument.Load((string)e.Argument);
        var items = new List<ListViewItem>();
        foreach (var item in rssDoc.XPathSelectElements("//item"))
        {
            var listItem = new ListViewItem();
            listItem.Text = item.Element("title").Value;
            listItem.SubItems.Add(item.Element("link").Value);
            items.Add(listItem);
        }
        e.Result = items.ToArray();
    }

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        lstView.Items.AddRange((ListViewItem[])e.Result);
    }
}
0 голосов
/ 08 апреля 2011

Если вы используете .NET 3.5 или более позднюю версию, вы можете использовать тип SyndicationFeed для упрощения анализа RSS-канала.

Я адаптирую пример кода Дарина Димитрова здесь:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
using System.ServiceModel.Syndication;
using System.Xml.Linq;
using System.Xml.XPath;

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        backgroundWorker1.RunWorkerAsync(txtUrl.Text);
    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        var reader = new XmlTextReader((string)e.Argument);
        var feed = SyndicationFeed.Load(reader);
        var items = new List<ListViewItem>();
        foreach (var item in feed.Items)
        {
            var listItem = new ListViewItem();
            listItem.Text = item.Title;
            foreach (var link in item.Links)
            {
                listItem.SubItems.Add(link.Uri.AbsoluteUri);
            }
            items.Add(listItem);
        }
        e.Result = items.ToArray();
    }

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        lstView.Items.AddRange((ListViewItem[])e.Result);
    }
}
0 голосов
/ 08 апреля 2011

Если вы используете .net 4.0, вы можете использовать систему задач для еще более простого подхода и, возможно, лучшей производительности.

  foreach (var item in rssDoc.XPathSelectElements("//item"))
  {
    Task fetch = new Task(() =>
    {
     // Go to server and get data....
     // Add Data to UI...
    });

    fetch.Start();
  }

Основное преимущество здесь заключается в том, что система задач будет решать, как и когдазапустить каждую операцию извлечения.Теоретически каждая операция будет выполняться в своем собственном потоке, поэтому будет активна одна или несколько за раз вместо одной, которую вы видели бы в обычном цикле.Система достаточно хороша, чтобы выполнить некоторую балансировку нагрузки для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...