读取RSS源时程序会锁定

时间:2012-08-25 20:57:35

标签: c# multithreading rss

我自己创建了一个读取RSS源的类,并将它们返回给我的主类。我用于此的代码是:

public List<Post> getLatestPosts()
{
    this.rssReader = new XmlTextReader(this.rssUrl);
    this.rssDoc = new XmlDocument();

    // Load the XML content into rssDoc
    rssDoc.Load(rssReader);

    // ... other code to parse XML ... //
}

现在,当我拨打getLatestPosts()时,我的应用程序会锁定几秒钟。我假设是因为这是应用程序请求RSS提要所需的时间(网络延迟等)。

我想改变它,所以我的程序没有锁定,而只是等待响应。我有想法在我的主要表单中使用线程,但我对如何捕获getLatestPosts()得到的任何RSS数据感到困惑。

如果我在我的按钮中执行此操作,请单击我的主表单:

private void bGetLatestPosts_Click(object sender, EventArgs e)
{
    Thread thread = new Thread(new ThreadStart(rssReader.getLatestPosts()));
}

我没有捕获getLatestPosts()返回的任何内容。

我对线程完全不熟悉(这主要是我一直在努力学习它们)但我确实在C#中有一些经验。

感谢。

1 个答案:

答案 0 :(得分:2)

我假设您正在编写WinForms应用程序。编写响应式WinForms应用程序有两个重要的规则:

  • 您在主UI线程上执行的所有操作都应该快速完成。
  • 您无法从主线程以外的任何线程访问控件。

要解决您的问题,请在BackgroundWorker

中运行您的代码
  

BackgroundWorker类允许您在单独的专用线程上运行操作。下载和数据库事务等耗时的操作可能会导致用户界面(UI)在运行时停止响应。当您需要响应式UI并且您遇到与此类操作相关的长时间延迟时,BackgroundWorker类提供了一种方便的解决方案。

     

要在后台执行耗时的操作,请创建BackgroundWorker并侦听报告操作进度的事件,并在操作完成时发出信号。您可以以编程方式创建BackgroundWorker,也可以从“工具箱”的“组件”选项卡将其拖到窗体上。如果在Windows窗体设计器中创建BackgroundWorker,它将显示在“组件托盘”中,其属性将显示在“属性”窗口中。

     

要设置后台操作,请为DoWork事件添加事件处理程序。在此事件处理程序中调用耗时的操作。要启动该操作,请调用RunWorkerAsync。要接收进度更新通知,请处理ProgressChanged事件。要在操作完成时接收通知,请处理RunWorkerCompleted事件。

以下是一些可能对您有用的代码:

private void bGetLatestPosts_Click(object sender, EventArgs e)
{
    bGetLatestPosts.Enabled = false;
    backgroundWorker.RunWorkerAsync();
}

private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
    e.Result = getLatestPosts();
}

private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if (e.Error != null)
    {
        // Handle exception...
    }
    else
    {
        List<Post> result = (List<Post>)e.Result;
        // Update GUI...
    }
    bGetLatestPosts.Enabled = true;
}