2013-11-01 2 views
1

Я использую следующий код:Еогеасп заявление дает ошибку

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

Я получаю сообщение об ошибке:

Error 1 foreach statement cannot operate on variables of type 'System.Threading.Tasks.Task(System.Collections.Generic.List(Cricket.MainPage.RssNews))' because 'System.Threading.Tasks.Task(System.Collections.Generic.List(Cricket.MainPage.RssNews))' does not contain a public definition for '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(); 
     } 
    } 
+0

Что 'RssReader.Read' возвращается? – Habib

+0

хотя программа не работает. Она предназначена для чтения из фида, всего xml фида. – YashVj

+0

Опубликуйте свой код для метода 'RssReader.Read()'. –

ответ

1

Я думаю, что вам не хватает в await заявление.

Это s имеет тип Task<List<RssNews>>.

Вы либо должны это

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(); 
} 
+0

@ Downvoter дайте мне знать, почему? Если вы не можете дать повод, не проголосуйте за него –

+1

+1, это выглядит хорошо, я не уверен, почему он был опущен. – Habib

+1

Я не был downvoter, но когда вы делаете «.Result», вам не нужно «ждать». –

0

Вы используете саму задачу в цикле. Вам необходимо использовать свойство «Результат»

foreach (RssNews rs in s.Result) 

поскольку из-за исключения представляется список, который будет возвращен.

+0

Спасибо за помощь! – YashVj

6

Вы должны использовать 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); 
+0

Это будет работать при условии, что пользователь находится на .NET 4.5 –

+0

Я сделал это Mr.Cleary, После этого мы создаем метод async, метод возвращает тип строки, который не принимается, поэтому дает ошибку! Спасибо за помощь! – YashVj

+0

@AllanElder Что, учитывая, что редактирование показывает метод async, явно имеет место. – Servy

Смежные вопросы