2015-05-07 3 views
1

Я делаю приложение winform, где я могу ввести имя игрока из игры Tibia. Когда я ввожу имя игрока, он отправляется на сайт (www.tibia.com) и ищет игрока, а также получает некоторые данные об игроке. В этом случае: возвращает имя, призвание и уровень. Для этого я использую HtmlAgilityPack, который захватывает данные для меня с веб-сайта.Не удается вставить строку в список или текстовое поле?

У меня есть три строковые переменные для этого: charname, voc и lvl.

Когда я получаю данные в переменных, я могу сделать messagboxes для их печати. Нравится:

MessageBox.Show("Your name is: " + charname); 

И это прекрасно работает.

Но я не могу добавить их в свой списокView (называемый: characterList) или текстовое поле (textBox1). Приложение аварийно завершает работу и дает мне эту ошибку:

An unhandled exception of type 'System.AggregateException' occurred in mscorlib.dll

И я просто не могу это исправить. Я сделал все, что мог.

Вот мой код:

//Goes to the website and grabs the data from the table 
    static async Task<List<List<string>>> GetPlayers() 
    { 
     playername.Replace(" ", "+"); 
     string url = "https://secure.tibia.com/community/?subtopic=characters&name=" + playername; 
     using (var client = new HttpClient()) 
     { 
      var html = await client.GetStringAsync(url); 
      var doc = new HtmlAgilityPack.HtmlDocument(); 

      doc.LoadHtml(html); 

      var table = doc.DocumentNode.SelectSingleNode("//table[@cellpadding='4']"); 
      return table.Descendants("tr") 
         .Skip(1) 
         .Select(tr => tr.Descendants("td") 
         .Select(td => WebUtility.HtmlDecode(td.InnerText)) 
         .ToList()) 
         .ToList(); 
     } 
    } 

А вот мой код, чтобы пройти через данные, которые он нашел, и добавить его в ListView (characterList):

private void addCharacter_Click(object sender, EventArgs e) 
    { 
     playername = Interaction.InputBox("Please enter a character name.", "Input Character Name"); 
     if (playername.Length > 0) 
     { 
      //get the player data from the website 
      //name, vocation and level 
      //add their values to the 3 variables: charname, voc and lvl. 
      //and add them to the listview (characterList) 
      Task.Run(async() => 
      { 
       var players = await GetPlayers(); 

       foreach (var row in players) 
       { 
        if (row[0] == "Name:") 
        { 
         charname = row[1]; 
        } 
       } 

       foreach (var row in players) 
       { 
        if (row[0] == "Vocation:") 
        { 
         if (row[1] == "Druid" || row[1] == "Elder Druid") 
         { 
          voc = "ED"; 
         } 
         else if (row[1] == "Knight" || row[1] == "Elite Knight") 
         { 
          voc = "EK"; 
         } 
         else if (row[1] == "Paladin" || row[1] == "Royal Paladin") 
         { 
          voc = "RP"; 
         } 
         else if (row[1] == "Sorcerer" || row[1] == "Master Sorcerer") 
         { 
          voc = "MS"; 
         } 
         else if (row[1] == "None") 
         { 
          voc = "None"; 
         } 
        } 
       } 

       foreach (var row in players) 
       { 
        if (row[0] == "Level:") 
        { 
         lvl = row[1]; 
        } 
       } 


       if (charname.Length > 0 && lvl.Length > 0 && voc.Length > 0) 
       { 
        string[] row1 = { voc, lvl }; 
        characterList.Items.Add(charname).SubItems.AddRange(row1); 
       } 

      }).Wait(); 
     } 
     else if (playername.Length < 1) 
     { 
      MessageBox.Show("Invalid character name.", "Error"); 
     } 
    } 

Вот и иллюстрация веб-сайт и то, как он захватывает данные из таблиц.

image

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

Я также попытался с помощью кнопки добавить некоторые пользовательские данные самостоятельно в listView и это работает. Поэтому мой способ добавления данных не должен быть проблемой. Просто вместо того, чтобы напрямую вставлять текст, я хочу вставить переменные.

Посмотрите на этот пример, когда я вручную добавить данные с помощью кнопки: image2

+0

Вы отправили свой код для добавления данных в список или текстовое поле? Я не видел его – Kira

+0

Да, он находится в нижней части второго блока кода. В 'characterList.Items.Add' я удалил текст добавления в текстовый код, хотя это было просто для тестирования. Я просто хочу добавить строки в список. – aliazik

ответ

1

Я подозреваю, что эту линию:

characterList.Items.Add(charname).SubItems.AddRange(row1); 

... исполняемый на рабочем потоке; не работает, потому что рабочие потоки не-STA не могут обновлять пользовательский интерфейс; и таким образом бросает AggregateException, потому что он находится в Task.

Я уверен, что вам не нужен Task.Run() в вашем addCharacter_Click(), особенно когда вы все равно выполняете .Wait().

Изменить его:

private async void addCharacter_Click(object sender, EventArgs e) 
{ 
    playername = Interaction.InputBox("Please enter a character name.", "Input Character Name"); 
    if (playername.Length > 0) 
    { 
     //get the player data from the website 
     //name, vocation and level 
     //add their values to the 3 variables: charname, voc and lvl. 
     //and add them to the listview (characterList) 

      var players = await GetPlayers(); 

      foreach (var row in players) 
      { 
       if (row[0] == "Name:") 
       { 
        charname = row[1]; 
       } 
      } 
. 
. 
. 

Обратите внимание, как выше метод теперь был отмечен как async.

+0

Когда я удаляю Task.Run(), он дает мне другие ошибки, которые говорят, что мне нужна task.run(), так как это асинхронный. Проверьте это изображение: http://i.imgur.com/aPCoz8i.png – aliazik

+0

Обратите внимание, что я изменил подпись метода, чтобы включить 'async' выше. то есть 'private async void addCharacter_Click (отправитель объекта, EventArgs e)'. Вам нужно включить 'async'. Мне следовало бы больше сказать, что извините – MickyD

+0

@aliazik lol. Мне приятно, мой сэр. Желаю вам здоровья :) – MickyD

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