c#-交叉线程操作无效ListView

c#-交叉线程操作无效ListView,c#,multithreading,winforms,C#,Multithreading,Winforms,我试图使用线程从网站上窃取链接,但当我试图运行。它显示错误: 跨线程操作无效:从创建控件“listView1”的线程以外的线程访问控件“listView1” 我的代码: try { foreach (HtmlNode node in (IEnumerable<HtmlNode>)document.DocumentNode.SelectNodes("//table[@class='tbl' and @id='stats']//tr[@class='' or @class='bg

我试图使用线程从网站上窃取链接,但当我试图运行。它显示错误:

跨线程操作无效:从创建控件“listView1”的线程以外的线程访问控件“listView1”

我的代码:

try
{
    foreach (HtmlNode node in (IEnumerable<HtmlNode>)document.DocumentNode.SelectNodes("//table[@class='tbl' and @id='stats']//tr[@class='' or @class='bg']"))
    {
    HtmlAgilityPack.HtmlDocument document2 = new HtmlAgilityPack.HtmlDocument();
    document2.LoadHtml(node.InnerHtml);
    try
    {
    string str6 = document2.DocumentNode.SelectSingleNode("//td[2]//a").Attributes["href"].Value;
    string innerText = document2.DocumentNode.SelectSingleNode("//td[2]//a").InnerText;
    string[] items = new string[] { listView1.Items.Count + 1.ToString(), innerText, str6, "" };
    ListViewItem item = new ListViewItem(items);
    listView1.Items.Add(item);
    listView1.EnsureVisible(listView1.Items.Count - 1);
    }
    catch (Exception ex)
    {
    MessageBox.Show(ex.Message);
    }
    }
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message);
}
试试看
{
foreach(在(IEnumerable)document.DocumentNode.SelectNodes(//table[@class='tbl'和@id='stats']//tr[@class=''或@class='bg']))
{
HtmlAgilityPack.HtmlDocument document2=新的HtmlAgilityPack.HtmlDocument();
document2.LoadHtml(node.InnerHtml);
尝试
{
字符串str6=document2.DocumentNode.SelectSingleNode(“//td[2]//a”).Attributes[“href”].Value;
字符串innerText=document2.DocumentNode.SelectSingleNode(“//td[2]//a”).innerText;
字符串[]项=新字符串[]{listView1.items.Count+1.ToString(),innerText,str6,“”};
ListViewItem项目=新的ListViewItem(项目);
listView1.Items.Add(项目);
listView1.EnsureRevible(listView1.Items.Count-1);
}
捕获(例外情况除外)
{
MessageBox.Show(例如Message);
}
}
}
捕获(例外情况除外)
{
MessageBox.Show(例如Message);
}

这是因为控件的线程关联性。这些只能在创建它们的线程上更新
invokererequired
Invoke
提供了在同一线程上更新控件的方法:

        if (listView1.InvokeRequired)
        {
            listView1.Invoke((MethodInvoker) delegate()
            {
                ListViewItem item = new ListViewItem(items);
                listView1.Items.Add(item);
                listView1.EnsureVisible(listView1.Items.Count - 1); 
            });
        }

invokererequired
成员属性是您的朋友;)我怎样才能添加InvokerRequired?缩进也是你的朋友。求你了,你不需要添加它。它已经在那里了。在您的列表视图中。基本上,它告诉您是否可以继续,或者是否需要对GUI线程(STAThread…)进行调用。你可以这样做:
if(this.invokererequired){this.Invoke(…)}
记不住Invoke的确切语法,因为我很久没有用过C#。我想我上次使用它是在添加lambdas之前;)但通常为了避免重复的代码,我使用了一个else,并在listview上定义了一次实际的代码。与此问题的数百个现有副本相比,低质量的答案。如果你想写一篇规范文章,一定要付出至少一些努力