RSS阅读器多线程C#

RSS阅读器多线程C#,c#,multithreading,rss,C#,Multithreading,Rss,我想制作一个RSS阅读器,它可以同时获取多个新闻提要,而不会在获取提要时让我的应用程序“冻结”。要做到这一点,我希望一些代码在一个单独的线程中运行。我尝试了一些不同的方法,让它在一个单独的线程中运行,但我总是遇到例外。我的代码看起来像这个自动取款机: namespace NewsReader { public partial class Form1 : Form { XmlTextReader rssReader; XmlDocument rss

我想制作一个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);

                }
            }

        }
    }
名称空间新闻阅读器
{
公共部分类Form1:Form
{
XmlTextReader rssReader;
xmlsdocumentrssdoc;
xmlnoder节点;
XmlNode节点通道;
xmlnodenodeItem;
ListViewItem rowNews;
公共表格1()
{
初始化组件();
}
私有void btnRead_单击(对象发送者,事件参数e)
{
//创建一个XmlTextReader,用于读取输入字段中输入的url
rssReader=新的XmlTextReader(txtUrl.Text);
//创建xml文档以保存输入路径的内容
rssDoc=newxmldocument();
//将读取器中的xml内容加载到XmlDocument中
rssDoc.负载(rssReader);
//进行循环以搜索标记
对于(int i=0;i
}

有人举过一些如何处理这个问题的例子吗?非常感谢使用我的代码的代码示例:)

提前谢谢。

您可以结帐。下面是一个例子:

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);
    }
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用System.Windows.Forms;
使用System.Xml.Linq;
使用System.Xml.XPath;
公共部分类Form1:Form
{
公共表格1()
{
初始化组件();
}
私有无效按钮1\u单击(对象发送者,事件参数e)
{
backgroundWorker1.RunWorkerAsync(txtUrl.Text);
}
私有void backgroundWorker1\u DoWork(对象发送方,DoWorkEventArgs e)
{
var rssDoc=XDocument.Load((字符串)e.Argument);
var items=新列表();
foreach(rssDoc.XPathSelectElements(“//项”)中的变量项)
{
var listItem=新ListViewItem();
listItem.Text=item.Element(“标题”).Value;
listItem.SubItems.Add(item.Element(“link”).Value);
添加(列表项);
}
e、 结果=items.ToArray();
}
私有void backgroundWorker1\u RunWorkerCompleted(对象发送方,runworkercompletedeventarge)
{
lstView.Items.AddRange((ListViewItem[])e.Result);
}
}

如果您使用的是.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();
  }

这里的主要好处是任务系统将决定如何以及何时运行每个获取操作。理论上,每个操作都将在其自己的线程中运行,因此一次一个或多个操作将处于活动状态,而不仅仅是在正常循环中看到的一个操作。该系统也很好,可以为您进行一些负载平衡。

如果您使用的是.NET 3.5或更高版本,则可以使用该类型来简化RSS提要的解析

我在这里改编Darin Dimitrov的代码示例:

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);
    }
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用System.Windows.Forms;
使用System.ServiceModel.Syndication;
使用System.Xml.Linq;
使用System.Xml.XPath;
公共部分类Form1:Form
{
公共表格1()
{
初始化组件();
}
私有无效按钮1\u单击(对象发送者,事件参数e)
{
backgroundWorker1.RunWorkerAsync(txtUrl.Text);
}
私有void backgroundWorker1\u DoWork(对象发送方,DoWorkEventArgs e)
{
var reader=newXMLTextReader((字符串)e.Argument);
var feed=SyndicationFeed.Load(读卡器);
var items=新列表();
foreach(feed.Items中的变量项)
{
var listItem=新ListViewItem();
listItem.Text=项目名称;
foreach(item.Links中的var链接)
{
添加(link.Uri.AbsoluteUri);
}
添加(列表项);
}
e、 结果=items.ToArray();
}
私有void backgroundWorker1\u RunWorkerCompleted(对象发送方,runworkercompletedeventarge)
{
lstView.Items.AddRange((ListViewItem[])e.Result);
}
}