【问题标题】:foreach statement giving an errorforeach 语句给出错误
【发布时间】:2013-11-02 03:46:47
【问题描述】:

我正在使用以下代码:

private string covertRss(string url)
    {
        var s = RssReader.Read(url);
        StringBuilder sb = new StringBuilder();
        foreach (RssNews rs in s)   //ERROR LINE
        {
            sb.AppendLine(rs.Title);
            sb.AppendLine(rs.PublicationDate);
            sb.AppendLine(rs.Description);
        }

        return sb.ToString();
    }

我收到一个错误:

错误 1 ​​foreach 语句无法对“System.Threading.Tasks.Task(System.Collections.Generic.List(Cricket.MainPage.RssNews))”类型的变量进行操作,因为“System.Threading.Tasks.Task(System. Collections.Generic.List(Cricket.MainPage.RssNews))' 不包含 'GetEnumerator' 的公共定义

RssNews 类是:

public class RssNews
    {
        public string Title;
        public string PublicationDate;
        public string Description;

    }

我应该添加什么代码才能消除错误并且不影响代码的用途? 提前致谢!

RssReader.Read() 的代码

public class RssReader
    {
        public static async System.Threading.Tasks.Task<List<RssNews>> Read(string url)
        {
            HttpClient httpClient = new HttpClient();

            string result = await httpClient.GetStringAsync(url); 

            XDocument document = XDocument.Parse(result);

            return (from descendant in document.Descendants("item")
                    select new RssNews()
                    {
                        Description = descendant.Element("description").Value,
                        Title = descendant.Element("title").Value,
                        PublicationDate = descendant.Element("pubDate").Value
                    }).ToList();
        }
    }

【问题讨论】:

  • RssReader.Read 返回的是什么?
  • 虽然程序没有运行。它的目的是从提要中读取提要的整个 xml。
  • 发布RssReader.Read() 方法的代码。

标签: c# visual-studio-2012 foreach rss


【解决方案1】:

你需要使用await:

foreach (RssNews rs in await s)

或:

var s = await RssReader.Read(url);

不要不要使用Result;如果你这样做了,你可以很容易地cause a deadlock 我在我的博客上描述。

附带说明,我建议您阅读并遵循Task-based Asynchronous Pattern documentation 中的指南。如果你这样做了,你会发现你的方法Read应该被命名为ReadAsync,这给你的调用代码一个强烈的提示,它需要使用await

var s = await RssReader.ReadAsync(url);

【讨论】:

  • 我做了那个 Mr.Cleary ,之后,我们使方法异步,方法返回字符串类型,不接受,因此报错!感谢您的帮助!
  • @AllanElder 鉴于编辑显示async 方法,显然是这种情况。
  • @YashVj 您需要将返回类型更改为Task&lt;string&gt;
  • 那么下面的代码会返回一个错误:public MainPage() { this.InitializeComponent();字符串可读Rss; readableRss =covertRss("static.cricinfo.com/rss/livescores.xml"); textbox.Text = readableRss; } 错误是:错误 1 ​​不能隐式转换类型 'System.Threading.Tasks.Task' 到 'string'
  • @YashVj:那么你需要asynchronously initialize,正如我在我的博客中描述的那样。请注意,您的 UI 将需要一个额外的状态来“加载” - 大多数人只是在异步初始化进行时显示微调器或加载消息。
【解决方案2】:

我认为您缺少await 声明。

看来s 的类型是Task&lt;List&lt;RssNews&gt;&gt;

你要么需要这个

var s = await RssReader.Read(url);

var s = RssReader.Read(url).Result;//this is blocking call

当然,当你使用await时,你还需要标记方法async

这就是你的方法

private async Task<string> covertRss(string url)
{
    var s = await RssReader.Read(url);
    StringBuilder sb = new StringBuilder();
    foreach (RssNews rs in s)   //ERROR LINE
    {
        sb.AppendLine(rs.Title);
        sb.AppendLine(rs.PublicationDate);
        sb.AppendLine(rs.Description);
    }

    return sb.ToString();
}

【讨论】:

  • @Downvoter 告诉我为什么?如果您不能给出理由,请不要投反对票
  • +1,这看起来不错,我不知道为什么它被否决了。
  • 我不是投反对票的人,但是当您选择 .Result 时,您不需要 await 它。
  • @SriramSakthivel 我已经使方法异步。可以在代码中看到。还是报错!
  • 对不起,当我投反对票时,答案只是说“我认为你错过了等待声明”;从那以后,您似乎也对其进行了编辑以纳入我的答案。
【解决方案3】:

您正在循环中使用任务本身。您需要使用 Result 属性

foreach (RssNews rs in s.Result)

因为从异常来看,它似乎是一个将被返回的列表。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-18
    • 1970-01-01
    • 2014-06-08
    • 1970-01-01
    • 2016-09-10
    • 2018-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多