2015-05-07 58 views
1

我正在制作一个winform应用程序,我可以从一个名为Tibia的游戏中输入一个玩家的名字。当我输入玩家名称时,它会进入网站(www.tibia.com)并搜索玩家,并获得关于玩家的一些数据。在这种情况下:返回名称,职业和级别。为此,我使用HtmlAgilityPack,它从网站为我抓取数据。不能插入字符串到列表视图或文本框?

我有三个字符串变量:charname,voc和lvl。

当我将数据导入变量时,我可以制作消息框来打印它们。像:

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

而且工作正常。

但我似乎无法将它们添加到我的listView(称为: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工作线程不被允许更新UI;并因此抛出AggregateException,因为它在Task中。

我敢肯定,您不需要addCharacter_Click()中的Task.Run(),特别是当您执行.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(object sender,EventArgs e)'。你需要包含'async'。我应该更多地指出对不起 – MickyD

+0

@aliazik哈哈。我的荣幸是我的好先生。祝你顺利 :) – MickyD

相关问题