多线程中的System.InvalidOperationException怎么解决?

cah黎明就在眼前 2020-08-23 08:26:25



private void btnStart_Click(object sender, EventArgs e)//点击按钮开始加载数据
{
Thread thread = new Thread(() => {
loadSort();
loadNovelName();
loadNovelContent();
});
thread.Start();
}

private void loadSort()//加载分类
{
this.Invoke(new Action(() => {
cbSortName.SelectedIndex = -1;
cbSortName.Text = "正在加载....";
cbSortName.Enabled = false;
}));

HtmlAgilityPack.HtmlDocument htmlDocument = ReturnHD(url);
HtmlNode sortNode = htmlDocument.DocumentNode.SelectSingleNode("//div[@class = 'nav']");
HtmlNodeCollection listSort = sortNode.ChildNodes[1].ChildNodes;
ArrayList sorts = new ArrayList();
for(int i = 0,j=0;i < listSort.Count; i++)
{
if (listSort[i].ChildNodes.Count > 0) {
j++;
if (j > 2) {
HtmlNode node = listSort[i].ChildNodes[0];
string sortName = node.InnerHtml.Trim();
string href = node.Attributes["href"].Value;
sorts.Add(new novelSort(sortName, href));
//novelSort novel = new novelSort(sortName, href);
//cbSortName.Items.Add(novel);
}
}

}
cbSortName.DataSource = sorts;
//Control.CheckForIllegalCrossThreadCalls = false;
this.Invoke(new Action(()=> {
cbSortName.Enabled = true;
cbSortName.DisplayMember = "sortName";
cbSortName.ValueMember = "href";//使用另一种方法会失效!!!
cbSortName.SelectedIndex = 0;
}));


}

this.Invoke(new Action(() => {
cbSortName.SelectedIndex = -1;
cbSortName.Text = "正在加载....";
cbSortName.Enabled = false;
}));
其中this和cbSortName都出现了图二的异常,cbSortName.Text也出现了异常,这该怎么解决啊。
...全文
3346 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 15 楼 icoolno1 的回复:
[quote=引用 13 楼 icoolno1 的回复:][quote=引用 12 楼 icoolno1 的回复:][quote=引用 11 楼 cah黎明就在眼前 的回复:][quote=引用 9 楼 icoolno1 的回复:] 试了一下不行,它这个虽然出错了但捕获不到异常信息,而且程序能够运行起来
你这程序建了几个线程啊,除了Button事件里,是不是还有其它线程。 如果多个线程在跑,控件被其它线程改动了,会导致当前线程无法确切的属性值,就会报这个错。[/quote] 看到了,错误原因就在这,绑定的时候肯定会触发这个事件的,而ButtonClick还没完成,于是冲突了:

private void cbSortName_SelectedIndexChanged(object sender, EventArgs e)
        {
             
             
            Thread thread = new Thread(()=> { loadNovelName(); });
            thread.Start();
            //loadNovelName();
        }
[/quote] 试试改成这样,把控件的事件移除掉,改成代码中手动注册,比如:

 EventHandler cbSortNameEvent;
        EventHandler cbNovelNameEvent;

        public textSpider()
        {
            InitializeComponent();
            cbSortNameEvent = new EventHandler(cbSortName_SelectedIndexChanged);//实例化事件
            cbNovelNameEvent = new EventHandler(cbNovelName_SelectedIndexChanged);//实例化事件,当然其它事件依葫芦画瓢,这里举只两个例子作为参考。
        }

//
            cbSortName.Invoke(new MethodInvoker(delegate
            {
                cbSortName.SelectedIndex = -1;
                cbSortName.Text = "正在加载....";
                cbSortName.Enabled = false;

                cbSortName.SelectedIndexChanged -= cbSortNameEvent;//防止绑定过程中触发事件
            }));

//省略

 this.Invoke(new Action(() => {
                cbSortName.DataSource = sorts;
                cbSortName.Enabled = true;
                cbSortName.DisplayMember = "sortName";
                cbSortName.ValueMember = "href";//使用另一种方法会失效!!!
                cbSortName.SelectedIndexChanged += cbSortNameEvent; //绑定完了重新注册事件
                cbSortName.SelectedIndex = 0;
            }));
[/quote] 这样解决了绑定数据源触发SelectedIndexChanged事件,但是这个错误还在,好像不是这个引起的。。。。
  • 打赏
  • 举报
回复
引用 22 楼 icoolno1 的回复:
[quote=引用 21 楼 cah黎明就在眼前 的回复:][quote=引用 20 楼 icoolno1 的回复:][quote=引用 19 楼 cah黎明就在眼前 的回复:][quote=引用 17 楼 icoolno1 的回复:] button事件要这样写,不要同时在这里加载子项,又在indexchanged里绑定子项。

        private void btnStart_Click(object sender, EventArgs e)
        {
            Thread thread = new Thread(() =>
            {
                loadSort();
                //loadNovelName();
                //loadNovelContent();
            });
            thread.Start();
        }
这是我现在的代码

using HtmlAgilityPack;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace BaiduSpider
{
    public partial class textSpider : Form
    {
        public textSpider()
        {
            InitializeComponent();
            cbSortNameEvent = new EventHandler(cbSortName_SelectedIndexChanged);//实例化事件
            cbNovelNameEvent = new EventHandler(cbNovelName_SelectedIndexChanged);//实例化事件,当然其它事件依葫芦画瓢,这里举只两个例子作为参考。

        }
        EventHandler cbSortNameEvent;
        EventHandler cbNovelNameEvent;
        private string url = "https://www.biquge.com";
        private HtmlAgilityPack.HtmlDocument ReturnHD(string url)//返回该地址对应的html
        {
            HtmlWeb htmlWeb = new HtmlWeb();
            htmlWeb.OverrideEncoding = Encoding.GetEncoding("gbk");//设置解析字符集
            return htmlWeb.Load(url);
        }

        private HtmlAgilityPack.HtmlDocument ReturnHD1(string url)//返回该地址对应的html
        {
            HtmlWeb htmlWeb = new HtmlWeb();
            htmlWeb.OverrideEncoding = Encoding.GetEncoding("utf-8");//设置解析字符集
            return htmlWeb.Load(url);
        }


        private void textSpider_Load(object sender, EventArgs e)
        {
            
        }

        string contentsUrl;
        private void loadNovelContent()
        {
            this.Invoke(new Action(() => {
                cbContents.SelectedIndex = -1;
                cbContents.Text = "正在加载....";
                cbContents.Enabled = false;
                if(cbNovelName.SelectedValue != null)
                {
                    contentsUrl = url + cbNovelName.SelectedValue.ToString();
                }
                
            }));

            ArrayList cts = new ArrayList();
            HtmlAgilityPack.HtmlDocument htmlDocument = ReturnHD1(contentsUrl);
            HtmlNodeCollection contents = htmlDocument.DocumentNode.SelectNodes("//dd");
            if (contents.Count > 12)
            {
                for(int i = 12; i < contents.Count; i++)
                {
                    string href = contents[i].ChildNodes[1].Attributes["href"].Value;
                    string content = contents[i].ChildNodes[1].InnerHtml;
                    cts.Add(new contents(href, content));
                }
            }
            
            this.Invoke(new Action(()=> {
                cbContents.DataSource = cts;
                cbContents.DisplayMember = "content";
                cbContents.ValueMember = "href";
                cbContents.SelectedIndex = 0;
                cbContents.Enabled = true;

            }));

        }
        
        string sortUrl;
        private void loadNovelName()//加载当前分类下的小说
        {
            //Action action = new Action();
            
            
            this.Invoke(new Action(()=> {
                cbNovelName.SelectedIndex = -1;
                cbNovelName.Text = "正在加载....";
                cbNovelName.Enabled = false;
                this.sortUrl = cbSortName.SelectedValue.ToString();
                cbNovelName.SelectedIndexChanged -= cbNovelNameEvent;//防止绑定过程中触发事件
            }));

            if(sortUrl == "BaiduSpider.novelSort")//防止初始化cbSortName而引起的cbSortName_SelectedIndexChanged事件
            {
                return;
            }
            HtmlAgilityPack.HtmlDocument htmlDocument = ReturnHD(sortUrl);
            HtmlNodeCollection booksNode = htmlDocument.DocumentNode.SelectNodes("//span[@class = 's2']");
            ArrayList books = new ArrayList();  
            if(booksNode == null||booksNode.Count == 0)
            {
                return;
            }
            foreach(HtmlNode n in booksNode)
            {
                string href = n.ChildNodes[0].Attributes["href"].Value;
                string sortName = n.ChildNodes[0].InnerHtml.Trim();
                books.Add(new novelSort(sortName, href));
            }
            //MessageBox.Show("url = " + sortUrl);
            
            this.Invoke(new Action(()=> {
                cbNovelName.DataSource = books;
                cbNovelName.DisplayMember = "sortName";//名称必须和novelSort中对应
                cbNovelName.ValueMember = "href";
                cbNovelName.SelectedIndex = 0;
                cbNovelName.Enabled = true;
                cbNovelName.SelectedIndexChanged += cbNovelNameEvent;
            }));
            
        }

        private void loadSort()
        {
           
            cbSortName.Invoke(new MethodInvoker(delegate
            {

                cbSortName.SelectedIndexChanged -= cbSortNameEvent;//防止绑定过程中触发事件
                cbSortName.SelectedIndex = -1;
                    cbSortName.Text = "正在加载....";
                    cbSortName.Enabled = false;
             
            }));
            HtmlAgilityPack.HtmlDocument htmlDocument = ReturnHD(url);
            HtmlNode sortNode = htmlDocument.DocumentNode.SelectSingleNode("//div[@class = 'nav']");
            HtmlNodeCollection listSort = sortNode.ChildNodes[1].ChildNodes;
            ArrayList sorts = new ArrayList();
            for(int i = 0,j=0;i < listSort.Count; i++)
            {
                if (listSort[i].ChildNodes.Count > 0) {
                    j++;
                    if (j > 2) { 
                        HtmlNode node = listSort[i].ChildNodes[0];
                        string sortName = node.InnerHtml.Trim();
                        string href = node.Attributes["href"].Value;
                        sorts.Add(new novelSort(sortName, href));
                        //novelSort novel = new novelSort(sortName, href);
                        //cbSortName.Items.Add(novel);
                    }
                }

            }
            
            //Control.CheckForIllegalCrossThreadCalls = false;
            this.Invoke(new Action(()=> {
                cbSortName.DataSource = sorts;//必须放内部否则无效
                cbSortName.Enabled = true;
                cbSortName.DisplayMember = "sortName";
                cbSortName.ValueMember = "href";//使用另一种方法会失效!!!
                cbSortName.SelectedIndex = 0;
                cbSortName.SelectedIndexChanged += cbSortNameEvent;
            }));
            
            
        }

        private void cbSortName_SelectedIndexChanged(object sender, EventArgs e)
        {

            MessageBox.Show("cbSortName发生了改变");
            Thread thread = new Thread(()=> { loadNovelName(); });
            thread.Start();
            //loadNovelName();
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            Thread thread = new Thread(() => {
                loadSort();
                //loadNovelName();
                //loadNovelContent();
            });
            thread.Start();
        }

        private void cbNovelName_SelectedIndexChanged(object sender, EventArgs e)
        {
            MessageBox.Show("cbNovelName发生了改变");
            Thread thread = new Thread(() => { loadNovelContent(); });
            thread.Start();
        }
    }
}

[/quote] 没毛病,运行很正常。 [/quote] 对,运行是没问题,但是为什么在loadSort打断点往下执行到cbSortName.Invoke(new MethodInvoker(delegate { cbSortName.SelectedIndexChanged -= cbSortNameEvent;//防止绑定过程中触发事件 cbSortName.SelectedIndex = -1; cbSortName.Text = "正在加载...."; cbSortName.Enabled = false; }));SelectedIndex和Text会出现异常,是什么原因导致的啊[/quote] 可能有一些非进程内的线程在修改对象值,而调试器又不能中断这些线程的运行,就会出现这种情况。[/quote] 好的,非常感谢,麻烦您这么长时间
鸡窝里的毛 2020-08-25
  • 打赏
  • 举报
回复
引用 21 楼 cah黎明就在眼前 的回复:
[quote=引用 20 楼 icoolno1 的回复:][quote=引用 19 楼 cah黎明就在眼前 的回复:][quote=引用 17 楼 icoolno1 的回复:]
button事件要这样写,不要同时在这里加载子项,又在indexchanged里绑定子项。


private void btnStart_Click(object sender, EventArgs e)
{
Thread thread = new Thread(() =>
{
loadSort();
//loadNovelName();
//loadNovelContent();
});
thread.Start();
}

这是我现在的代码

using HtmlAgilityPack;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace BaiduSpider
{
public partial class textSpider : Form
{
public textSpider()
{
InitializeComponent();
cbSortNameEvent = new EventHandler(cbSortName_SelectedIndexChanged);//实例化事件
cbNovelNameEvent = new EventHandler(cbNovelName_SelectedIndexChanged);//实例化事件,当然其它事件依葫芦画瓢,这里举只两个例子作为参考。

}
EventHandler cbSortNameEvent;
EventHandler cbNovelNameEvent;
private string url = "https://www.biquge.com";
private HtmlAgilityPack.HtmlDocument ReturnHD(string url)//返回该地址对应的html
{
HtmlWeb htmlWeb = new HtmlWeb();
htmlWeb.OverrideEncoding = Encoding.GetEncoding("gbk");//设置解析字符集
return htmlWeb.Load(url);
}

private HtmlAgilityPack.HtmlDocument ReturnHD1(string url)//返回该地址对应的html
{
HtmlWeb htmlWeb = new HtmlWeb();
htmlWeb.OverrideEncoding = Encoding.GetEncoding("utf-8");//设置解析字符集
return htmlWeb.Load(url);
}


private void textSpider_Load(object sender, EventArgs e)
{

}

string contentsUrl;
private void loadNovelContent()
{
this.Invoke(new Action(() => {
cbContents.SelectedIndex = -1;
cbContents.Text = "正在加载....";
cbContents.Enabled = false;
if(cbNovelName.SelectedValue != null)
{
contentsUrl = url + cbNovelName.SelectedValue.ToString();
}

}));

ArrayList cts = new ArrayList();
HtmlAgilityPack.HtmlDocument htmlDocument = ReturnHD1(contentsUrl);
HtmlNodeCollection contents = htmlDocument.DocumentNode.SelectNodes("//dd");
if (contents.Count > 12)
{
for(int i = 12; i < contents.Count; i++)
{
string href = contents[i].ChildNodes[1].Attributes["href"].Value;
string content = contents[i].ChildNodes[1].InnerHtml;
cts.Add(new contents(href, content));
}
}

this.Invoke(new Action(()=> {
cbContents.DataSource = cts;
cbContents.DisplayMember = "content";
cbContents.ValueMember = "href";
cbContents.SelectedIndex = 0;
cbContents.Enabled = true;

}));

}

string sortUrl;
private void loadNovelName()//加载当前分类下的小说
{
//Action action = new Action();


this.Invoke(new Action(()=> {
cbNovelName.SelectedIndex = -1;
cbNovelName.Text = "正在加载....";
cbNovelName.Enabled = false;
this.sortUrl = cbSortName.SelectedValue.ToString();
cbNovelName.SelectedIndexChanged -= cbNovelNameEvent;//防止绑定过程中触发事件
}));

if(sortUrl == "BaiduSpider.novelSort")//防止初始化cbSortName而引起的cbSortName_SelectedIndexChanged事件
{
return;
}
HtmlAgilityPack.HtmlDocument htmlDocument = ReturnHD(sortUrl);
HtmlNodeCollection booksNode = htmlDocument.DocumentNode.SelectNodes("//span[@class = 's2']");
ArrayList books = new ArrayList();
if(booksNode == null||booksNode.Count == 0)
{
return;
}
foreach(HtmlNode n in booksNode)
{
string href = n.ChildNodes[0].Attributes["href"].Value;
string sortName = n.ChildNodes[0].InnerHtml.Trim();
books.Add(new novelSort(sortName, href));
}
//MessageBox.Show("url = " + sortUrl);

this.Invoke(new Action(()=> {
cbNovelName.DataSource = books;
cbNovelName.DisplayMember = "sortName";//名称必须和novelSort中对应
cbNovelName.ValueMember = "href";
cbNovelName.SelectedIndex = 0;
cbNovelName.Enabled = true;
cbNovelName.SelectedIndexChanged += cbNovelNameEvent;
}));

}

private void loadSort()
{

cbSortName.Invoke(new MethodInvoker(delegate
{

cbSortName.SelectedIndexChanged -= cbSortNameEvent;//防止绑定过程中触发事件
cbSortName.SelectedIndex = -1;
cbSortName.Text = "正在加载....";
cbSortName.Enabled = false;

}));
HtmlAgilityPack.HtmlDocument htmlDocument = ReturnHD(url);
HtmlNode sortNode = htmlDocument.DocumentNode.SelectSingleNode("//div[@class = 'nav']");
HtmlNodeCollection listSort = sortNode.ChildNodes[1].ChildNodes;
ArrayList sorts = new ArrayList();
for(int i = 0,j=0;i < listSort.Count; i++)
{
if (listSort[i].ChildNodes.Count > 0) {
j++;
if (j > 2) {
HtmlNode node = listSort[i].ChildNodes[0];
string sortName = node.InnerHtml.Trim();
string href = node.Attributes["href"].Value;
sorts.Add(new novelSort(sortName, href));
//novelSort novel = new novelSort(sortName, href);
//cbSortName.Items.Add(novel);
}
}

}

//Control.CheckForIllegalCrossThreadCalls = false;
this.Invoke(new Action(()=> {
cbSortName.DataSource = sorts;//必须放内部否则无效
cbSortName.Enabled = true;
cbSortName.DisplayMember = "sortName";
cbSortName.ValueMember = "href";//使用另一种方法会失效!!!
cbSortName.SelectedIndex = 0;
cbSortName.SelectedIndexChanged += cbSortNameEvent;
}));


}

private void cbSortName_SelectedIndexChanged(object sender, EventArgs e)
{

MessageBox.Show("cbSortName发生了改变");
Thread thread = new Thread(()=> { loadNovelName(); });
thread.Start();
//loadNovelName();
}

private void btnStart_Click(object sender, EventArgs e)
{
Thread thread = new Thread(() => {
loadSort();
//loadNovelName();
//loadNovelContent();
});
thread.Start();
}

private void cbNovelName_SelectedIndexChanged(object sender, EventArgs e)
{
MessageBox.Show("cbNovelName发生了改变");
Thread thread = new Thread(() => { loadNovelContent(); });
thread.Start();
}
}
}

[/quote]

没毛病,运行很正常。

[/quote]
对,运行是没问题,但是为什么在loadSort打断点往下执行到cbSortName.Invoke(new MethodInvoker(delegate
{

cbSortName.SelectedIndexChanged -= cbSortNameEvent;//防止绑定过程中触发事件
cbSortName.SelectedIndex = -1;
cbSortName.Text = "正在加载....";
cbSortName.Enabled = false;

}));SelectedIndex和Text会出现异常,是什么原因导致的啊[/quote]

可能有一些非进程内的线程在修改对象值,而调试器又不能中断这些线程的运行,就会出现这种情况。
  • 打赏
  • 举报
回复
引用 20 楼 icoolno1 的回复:
[quote=引用 19 楼 cah黎明就在眼前 的回复:][quote=引用 17 楼 icoolno1 的回复:] button事件要这样写,不要同时在这里加载子项,又在indexchanged里绑定子项。

        private void btnStart_Click(object sender, EventArgs e)
        {
            Thread thread = new Thread(() =>
            {
                loadSort();
                //loadNovelName();
                //loadNovelContent();
            });
            thread.Start();
        }
这是我现在的代码

using HtmlAgilityPack;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace BaiduSpider
{
    public partial class textSpider : Form
    {
        public textSpider()
        {
            InitializeComponent();
            cbSortNameEvent = new EventHandler(cbSortName_SelectedIndexChanged);//实例化事件
            cbNovelNameEvent = new EventHandler(cbNovelName_SelectedIndexChanged);//实例化事件,当然其它事件依葫芦画瓢,这里举只两个例子作为参考。

        }
        EventHandler cbSortNameEvent;
        EventHandler cbNovelNameEvent;
        private string url = "https://www.biquge.com";
        private HtmlAgilityPack.HtmlDocument ReturnHD(string url)//返回该地址对应的html
        {
            HtmlWeb htmlWeb = new HtmlWeb();
            htmlWeb.OverrideEncoding = Encoding.GetEncoding("gbk");//设置解析字符集
            return htmlWeb.Load(url);
        }

        private HtmlAgilityPack.HtmlDocument ReturnHD1(string url)//返回该地址对应的html
        {
            HtmlWeb htmlWeb = new HtmlWeb();
            htmlWeb.OverrideEncoding = Encoding.GetEncoding("utf-8");//设置解析字符集
            return htmlWeb.Load(url);
        }


        private void textSpider_Load(object sender, EventArgs e)
        {
            
        }

        string contentsUrl;
        private void loadNovelContent()
        {
            this.Invoke(new Action(() => {
                cbContents.SelectedIndex = -1;
                cbContents.Text = "正在加载....";
                cbContents.Enabled = false;
                if(cbNovelName.SelectedValue != null)
                {
                    contentsUrl = url + cbNovelName.SelectedValue.ToString();
                }
                
            }));

            ArrayList cts = new ArrayList();
            HtmlAgilityPack.HtmlDocument htmlDocument = ReturnHD1(contentsUrl);
            HtmlNodeCollection contents = htmlDocument.DocumentNode.SelectNodes("//dd");
            if (contents.Count > 12)
            {
                for(int i = 12; i < contents.Count; i++)
                {
                    string href = contents[i].ChildNodes[1].Attributes["href"].Value;
                    string content = contents[i].ChildNodes[1].InnerHtml;
                    cts.Add(new contents(href, content));
                }
            }
            
            this.Invoke(new Action(()=> {
                cbContents.DataSource = cts;
                cbContents.DisplayMember = "content";
                cbContents.ValueMember = "href";
                cbContents.SelectedIndex = 0;
                cbContents.Enabled = true;

            }));

        }
        
        string sortUrl;
        private void loadNovelName()//加载当前分类下的小说
        {
            //Action action = new Action();
            
            
            this.Invoke(new Action(()=> {
                cbNovelName.SelectedIndex = -1;
                cbNovelName.Text = "正在加载....";
                cbNovelName.Enabled = false;
                this.sortUrl = cbSortName.SelectedValue.ToString();
                cbNovelName.SelectedIndexChanged -= cbNovelNameEvent;//防止绑定过程中触发事件
            }));

            if(sortUrl == "BaiduSpider.novelSort")//防止初始化cbSortName而引起的cbSortName_SelectedIndexChanged事件
            {
                return;
            }
            HtmlAgilityPack.HtmlDocument htmlDocument = ReturnHD(sortUrl);
            HtmlNodeCollection booksNode = htmlDocument.DocumentNode.SelectNodes("//span[@class = 's2']");
            ArrayList books = new ArrayList();  
            if(booksNode == null||booksNode.Count == 0)
            {
                return;
            }
            foreach(HtmlNode n in booksNode)
            {
                string href = n.ChildNodes[0].Attributes["href"].Value;
                string sortName = n.ChildNodes[0].InnerHtml.Trim();
                books.Add(new novelSort(sortName, href));
            }
            //MessageBox.Show("url = " + sortUrl);
            
            this.Invoke(new Action(()=> {
                cbNovelName.DataSource = books;
                cbNovelName.DisplayMember = "sortName";//名称必须和novelSort中对应
                cbNovelName.ValueMember = "href";
                cbNovelName.SelectedIndex = 0;
                cbNovelName.Enabled = true;
                cbNovelName.SelectedIndexChanged += cbNovelNameEvent;
            }));
            
        }

        private void loadSort()
        {
           
            cbSortName.Invoke(new MethodInvoker(delegate
            {

                cbSortName.SelectedIndexChanged -= cbSortNameEvent;//防止绑定过程中触发事件
                cbSortName.SelectedIndex = -1;
                    cbSortName.Text = "正在加载....";
                    cbSortName.Enabled = false;
             
            }));
            HtmlAgilityPack.HtmlDocument htmlDocument = ReturnHD(url);
            HtmlNode sortNode = htmlDocument.DocumentNode.SelectSingleNode("//div[@class = 'nav']");
            HtmlNodeCollection listSort = sortNode.ChildNodes[1].ChildNodes;
            ArrayList sorts = new ArrayList();
            for(int i = 0,j=0;i < listSort.Count; i++)
            {
                if (listSort[i].ChildNodes.Count > 0) {
                    j++;
                    if (j > 2) { 
                        HtmlNode node = listSort[i].ChildNodes[0];
                        string sortName = node.InnerHtml.Trim();
                        string href = node.Attributes["href"].Value;
                        sorts.Add(new novelSort(sortName, href));
                        //novelSort novel = new novelSort(sortName, href);
                        //cbSortName.Items.Add(novel);
                    }
                }

            }
            
            //Control.CheckForIllegalCrossThreadCalls = false;
            this.Invoke(new Action(()=> {
                cbSortName.DataSource = sorts;//必须放内部否则无效
                cbSortName.Enabled = true;
                cbSortName.DisplayMember = "sortName";
                cbSortName.ValueMember = "href";//使用另一种方法会失效!!!
                cbSortName.SelectedIndex = 0;
                cbSortName.SelectedIndexChanged += cbSortNameEvent;
            }));
            
            
        }

        private void cbSortName_SelectedIndexChanged(object sender, EventArgs e)
        {

            MessageBox.Show("cbSortName发生了改变");
            Thread thread = new Thread(()=> { loadNovelName(); });
            thread.Start();
            //loadNovelName();
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            Thread thread = new Thread(() => {
                loadSort();
                //loadNovelName();
                //loadNovelContent();
            });
            thread.Start();
        }

        private void cbNovelName_SelectedIndexChanged(object sender, EventArgs e)
        {
            MessageBox.Show("cbNovelName发生了改变");
            Thread thread = new Thread(() => { loadNovelContent(); });
            thread.Start();
        }
    }
}

[/quote] 没毛病,运行很正常。 [/quote] 对,运行是没问题,但是为什么在loadSort打断点往下执行到cbSortName.Invoke(new MethodInvoker(delegate { cbSortName.SelectedIndexChanged -= cbSortNameEvent;//防止绑定过程中触发事件 cbSortName.SelectedIndex = -1; cbSortName.Text = "正在加载...."; cbSortName.Enabled = false; }));SelectedIndex和Text会出现异常,是什么原因导致的啊
鸡窝里的毛 2020-08-25
  • 打赏
  • 举报
回复
引用 19 楼 cah黎明就在眼前 的回复:
[quote=引用 17 楼 icoolno1 的回复:]
button事件要这样写,不要同时在这里加载子项,又在indexchanged里绑定子项。


private void btnStart_Click(object sender, EventArgs e)
{
Thread thread = new Thread(() =>
{
loadSort();
//loadNovelName();
//loadNovelContent();
});
thread.Start();
}

这是我现在的代码

using HtmlAgilityPack;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace BaiduSpider
{
public partial class textSpider : Form
{
public textSpider()
{
InitializeComponent();
cbSortNameEvent = new EventHandler(cbSortName_SelectedIndexChanged);//实例化事件
cbNovelNameEvent = new EventHandler(cbNovelName_SelectedIndexChanged);//实例化事件,当然其它事件依葫芦画瓢,这里举只两个例子作为参考。

}
EventHandler cbSortNameEvent;
EventHandler cbNovelNameEvent;
private string url = "https://www.biquge.com";
private HtmlAgilityPack.HtmlDocument ReturnHD(string url)//返回该地址对应的html
{
HtmlWeb htmlWeb = new HtmlWeb();
htmlWeb.OverrideEncoding = Encoding.GetEncoding("gbk");//设置解析字符集
return htmlWeb.Load(url);
}

private HtmlAgilityPack.HtmlDocument ReturnHD1(string url)//返回该地址对应的html
{
HtmlWeb htmlWeb = new HtmlWeb();
htmlWeb.OverrideEncoding = Encoding.GetEncoding("utf-8");//设置解析字符集
return htmlWeb.Load(url);
}


private void textSpider_Load(object sender, EventArgs e)
{

}

string contentsUrl;
private void loadNovelContent()
{
this.Invoke(new Action(() => {
cbContents.SelectedIndex = -1;
cbContents.Text = "正在加载....";
cbContents.Enabled = false;
if(cbNovelName.SelectedValue != null)
{
contentsUrl = url + cbNovelName.SelectedValue.ToString();
}

}));

ArrayList cts = new ArrayList();
HtmlAgilityPack.HtmlDocument htmlDocument = ReturnHD1(contentsUrl);
HtmlNodeCollection contents = htmlDocument.DocumentNode.SelectNodes("//dd");
if (contents.Count > 12)
{
for(int i = 12; i < contents.Count; i++)
{
string href = contents[i].ChildNodes[1].Attributes["href"].Value;
string content = contents[i].ChildNodes[1].InnerHtml;
cts.Add(new contents(href, content));
}
}

this.Invoke(new Action(()=> {
cbContents.DataSource = cts;
cbContents.DisplayMember = "content";
cbContents.ValueMember = "href";
cbContents.SelectedIndex = 0;
cbContents.Enabled = true;

}));

}

string sortUrl;
private void loadNovelName()//加载当前分类下的小说
{
//Action action = new Action();


this.Invoke(new Action(()=> {
cbNovelName.SelectedIndex = -1;
cbNovelName.Text = "正在加载....";
cbNovelName.Enabled = false;
this.sortUrl = cbSortName.SelectedValue.ToString();
cbNovelName.SelectedIndexChanged -= cbNovelNameEvent;//防止绑定过程中触发事件
}));

if(sortUrl == "BaiduSpider.novelSort")//防止初始化cbSortName而引起的cbSortName_SelectedIndexChanged事件
{
return;
}
HtmlAgilityPack.HtmlDocument htmlDocument = ReturnHD(sortUrl);
HtmlNodeCollection booksNode = htmlDocument.DocumentNode.SelectNodes("//span[@class = 's2']");
ArrayList books = new ArrayList();
if(booksNode == null||booksNode.Count == 0)
{
return;
}
foreach(HtmlNode n in booksNode)
{
string href = n.ChildNodes[0].Attributes["href"].Value;
string sortName = n.ChildNodes[0].InnerHtml.Trim();
books.Add(new novelSort(sortName, href));
}
//MessageBox.Show("url = " + sortUrl);

this.Invoke(new Action(()=> {
cbNovelName.DataSource = books;
cbNovelName.DisplayMember = "sortName";//名称必须和novelSort中对应
cbNovelName.ValueMember = "href";
cbNovelName.SelectedIndex = 0;
cbNovelName.Enabled = true;
cbNovelName.SelectedIndexChanged += cbNovelNameEvent;
}));

}

private void loadSort()
{

cbSortName.Invoke(new MethodInvoker(delegate
{

cbSortName.SelectedIndexChanged -= cbSortNameEvent;//防止绑定过程中触发事件
cbSortName.SelectedIndex = -1;
cbSortName.Text = "正在加载....";
cbSortName.Enabled = false;

}));
HtmlAgilityPack.HtmlDocument htmlDocument = ReturnHD(url);
HtmlNode sortNode = htmlDocument.DocumentNode.SelectSingleNode("//div[@class = 'nav']");
HtmlNodeCollection listSort = sortNode.ChildNodes[1].ChildNodes;
ArrayList sorts = new ArrayList();
for(int i = 0,j=0;i < listSort.Count; i++)
{
if (listSort[i].ChildNodes.Count > 0) {
j++;
if (j > 2) {
HtmlNode node = listSort[i].ChildNodes[0];
string sortName = node.InnerHtml.Trim();
string href = node.Attributes["href"].Value;
sorts.Add(new novelSort(sortName, href));
//novelSort novel = new novelSort(sortName, href);
//cbSortName.Items.Add(novel);
}
}

}

//Control.CheckForIllegalCrossThreadCalls = false;
this.Invoke(new Action(()=> {
cbSortName.DataSource = sorts;//必须放内部否则无效
cbSortName.Enabled = true;
cbSortName.DisplayMember = "sortName";
cbSortName.ValueMember = "href";//使用另一种方法会失效!!!
cbSortName.SelectedIndex = 0;
cbSortName.SelectedIndexChanged += cbSortNameEvent;
}));


}

private void cbSortName_SelectedIndexChanged(object sender, EventArgs e)
{

MessageBox.Show("cbSortName发生了改变");
Thread thread = new Thread(()=> { loadNovelName(); });
thread.Start();
//loadNovelName();
}

private void btnStart_Click(object sender, EventArgs e)
{
Thread thread = new Thread(() => {
loadSort();
//loadNovelName();
//loadNovelContent();
});
thread.Start();
}

private void cbNovelName_SelectedIndexChanged(object sender, EventArgs e)
{
MessageBox.Show("cbNovelName发生了改变");
Thread thread = new Thread(() => { loadNovelContent(); });
thread.Start();
}
}
}

[/quote]

没毛病,运行很正常。

  • 打赏
  • 举报
回复
引用 17 楼 icoolno1 的回复:
button事件要这样写,不要同时在这里加载子项,又在indexchanged里绑定子项。

        private void btnStart_Click(object sender, EventArgs e)
        {
            Thread thread = new Thread(() =>
            {
                loadSort();
                //loadNovelName();
                //loadNovelContent();
            });
            thread.Start();
        }
这是我现在的代码

using HtmlAgilityPack;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace BaiduSpider
{
    public partial class textSpider : Form
    {
        public textSpider()
        {
            InitializeComponent();
            cbSortNameEvent = new EventHandler(cbSortName_SelectedIndexChanged);//实例化事件
            cbNovelNameEvent = new EventHandler(cbNovelName_SelectedIndexChanged);//实例化事件,当然其它事件依葫芦画瓢,这里举只两个例子作为参考。

        }
        EventHandler cbSortNameEvent;
        EventHandler cbNovelNameEvent;
        private string url = "https://www.biquge.com";
        private HtmlAgilityPack.HtmlDocument ReturnHD(string url)//返回该地址对应的html
        {
            HtmlWeb htmlWeb = new HtmlWeb();
            htmlWeb.OverrideEncoding = Encoding.GetEncoding("gbk");//设置解析字符集
            return htmlWeb.Load(url);
        }

        private HtmlAgilityPack.HtmlDocument ReturnHD1(string url)//返回该地址对应的html
        {
            HtmlWeb htmlWeb = new HtmlWeb();
            htmlWeb.OverrideEncoding = Encoding.GetEncoding("utf-8");//设置解析字符集
            return htmlWeb.Load(url);
        }


        private void textSpider_Load(object sender, EventArgs e)
        {
            
        }

        string contentsUrl;
        private void loadNovelContent()
        {
            this.Invoke(new Action(() => {
                cbContents.SelectedIndex = -1;
                cbContents.Text = "正在加载....";
                cbContents.Enabled = false;
                if(cbNovelName.SelectedValue != null)
                {
                    contentsUrl = url + cbNovelName.SelectedValue.ToString();
                }
                
            }));

            ArrayList cts = new ArrayList();
            HtmlAgilityPack.HtmlDocument htmlDocument = ReturnHD1(contentsUrl);
            HtmlNodeCollection contents = htmlDocument.DocumentNode.SelectNodes("//dd");
            if (contents.Count > 12)
            {
                for(int i = 12; i < contents.Count; i++)
                {
                    string href = contents[i].ChildNodes[1].Attributes["href"].Value;
                    string content = contents[i].ChildNodes[1].InnerHtml;
                    cts.Add(new contents(href, content));
                }
            }
            
            this.Invoke(new Action(()=> {
                cbContents.DataSource = cts;
                cbContents.DisplayMember = "content";
                cbContents.ValueMember = "href";
                cbContents.SelectedIndex = 0;
                cbContents.Enabled = true;

            }));

        }
        
        string sortUrl;
        private void loadNovelName()//加载当前分类下的小说
        {
            //Action action = new Action();
            
            
            this.Invoke(new Action(()=> {
                cbNovelName.SelectedIndex = -1;
                cbNovelName.Text = "正在加载....";
                cbNovelName.Enabled = false;
                this.sortUrl = cbSortName.SelectedValue.ToString();
                cbNovelName.SelectedIndexChanged -= cbNovelNameEvent;//防止绑定过程中触发事件
            }));

            if(sortUrl == "BaiduSpider.novelSort")//防止初始化cbSortName而引起的cbSortName_SelectedIndexChanged事件
            {
                return;
            }
            HtmlAgilityPack.HtmlDocument htmlDocument = ReturnHD(sortUrl);
            HtmlNodeCollection booksNode = htmlDocument.DocumentNode.SelectNodes("//span[@class = 's2']");
            ArrayList books = new ArrayList();  
            if(booksNode == null||booksNode.Count == 0)
            {
                return;
            }
            foreach(HtmlNode n in booksNode)
            {
                string href = n.ChildNodes[0].Attributes["href"].Value;
                string sortName = n.ChildNodes[0].InnerHtml.Trim();
                books.Add(new novelSort(sortName, href));
            }
            //MessageBox.Show("url = " + sortUrl);
            
            this.Invoke(new Action(()=> {
                cbNovelName.DataSource = books;
                cbNovelName.DisplayMember = "sortName";//名称必须和novelSort中对应
                cbNovelName.ValueMember = "href";
                cbNovelName.SelectedIndex = 0;
                cbNovelName.Enabled = true;
                cbNovelName.SelectedIndexChanged += cbNovelNameEvent;
            }));
            
        }

        private void loadSort()
        {
           
            cbSortName.Invoke(new MethodInvoker(delegate
            {

                cbSortName.SelectedIndexChanged -= cbSortNameEvent;//防止绑定过程中触发事件
                cbSortName.SelectedIndex = -1;
                    cbSortName.Text = "正在加载....";
                    cbSortName.Enabled = false;
             
            }));
            HtmlAgilityPack.HtmlDocument htmlDocument = ReturnHD(url);
            HtmlNode sortNode = htmlDocument.DocumentNode.SelectSingleNode("//div[@class = 'nav']");
            HtmlNodeCollection listSort = sortNode.ChildNodes[1].ChildNodes;
            ArrayList sorts = new ArrayList();
            for(int i = 0,j=0;i < listSort.Count; i++)
            {
                if (listSort[i].ChildNodes.Count > 0) {
                    j++;
                    if (j > 2) { 
                        HtmlNode node = listSort[i].ChildNodes[0];
                        string sortName = node.InnerHtml.Trim();
                        string href = node.Attributes["href"].Value;
                        sorts.Add(new novelSort(sortName, href));
                        //novelSort novel = new novelSort(sortName, href);
                        //cbSortName.Items.Add(novel);
                    }
                }

            }
            
            //Control.CheckForIllegalCrossThreadCalls = false;
            this.Invoke(new Action(()=> {
                cbSortName.DataSource = sorts;//必须放内部否则无效
                cbSortName.Enabled = true;
                cbSortName.DisplayMember = "sortName";
                cbSortName.ValueMember = "href";//使用另一种方法会失效!!!
                cbSortName.SelectedIndex = 0;
                cbSortName.SelectedIndexChanged += cbSortNameEvent;
            }));
            
            
        }

        private void cbSortName_SelectedIndexChanged(object sender, EventArgs e)
        {

            MessageBox.Show("cbSortName发生了改变");
            Thread thread = new Thread(()=> { loadNovelName(); });
            thread.Start();
            //loadNovelName();
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            Thread thread = new Thread(() => {
                loadSort();
                //loadNovelName();
                //loadNovelContent();
            });
            thread.Start();
        }

        private void cbNovelName_SelectedIndexChanged(object sender, EventArgs e)
        {
            MessageBox.Show("cbNovelName发生了改变");
            Thread thread = new Thread(() => { loadNovelContent(); });
            thread.Start();
        }
    }
}

  • 打赏
  • 举报
回复
引用 17 楼 icoolno1 的回复:
button事件要这样写,不要同时在这里加载子项,又在indexchanged里绑定子项。

        private void btnStart_Click(object sender, EventArgs e)
        {
            Thread thread = new Thread(() =>
            {
                loadSort();
                //loadNovelName();
                //loadNovelContent();
            });
            thread.Start();
        }
这样写之后,点击按钮运行到loadSort()还是这种错误,是不是我这本身的语句问题啊 cbSortName.Invoke(new MethodInvoker(delegate { cbSortName.SelectedIndexChanged -= cbSortNameEvent;//防止绑定过程中触发事件 cbSortName.SelectedIndex = -1; cbSortName.Text = "正在加载...."; cbSortName.Enabled = false; }));
鸡窝里的毛 2020-08-25
  • 打赏
  • 举报
回复
引用 16 楼 cah黎明就在眼前 的回复:
[quote=引用 15 楼 icoolno1 的回复:][quote=引用 13 楼 icoolno1 的回复:][quote=引用 12 楼 icoolno1 的回复:][quote=引用 11 楼 cah黎明就在眼前 的回复:][quote=引用 9 楼 icoolno1 的回复:]
试了一下不行,它这个虽然出错了但捕获不到异常信息,而且程序能够运行起来

你这程序建了几个线程啊,除了Button事件里,是不是还有其它线程。

如果多个线程在跑,控件被其它线程改动了,会导致当前线程无法确切的属性值,就会报这个错。[/quote]

看到了,错误原因就在这,绑定的时候肯定会触发这个事件的,而ButtonClick还没完成,于是冲突了:

private void cbSortName_SelectedIndexChanged(object sender, EventArgs e)
{


Thread thread = new Thread(()=> { loadNovelName(); });
thread.Start();
//loadNovelName();
}
[/quote]

试试改成这样,把控件的事件移除掉,改成代码中手动注册,比如:


EventHandler cbSortNameEvent;
EventHandler cbNovelNameEvent;

public textSpider()
{
InitializeComponent();
cbSortNameEvent = new EventHandler(cbSortName_SelectedIndexChanged);//实例化事件
cbNovelNameEvent = new EventHandler(cbNovelName_SelectedIndexChanged);//实例化事件,当然其它事件依葫芦画瓢,这里举只两个例子作为参考。
}

//
cbSortName.Invoke(new MethodInvoker(delegate
{
cbSortName.SelectedIndex = -1;
cbSortName.Text = "正在加载....";
cbSortName.Enabled = false;

cbSortName.SelectedIndexChanged -= cbSortNameEvent;//防止绑定过程中触发事件
}));

//省略

this.Invoke(new Action(() => {
cbSortName.DataSource = sorts;
cbSortName.Enabled = true;
cbSortName.DisplayMember = "sortName";
cbSortName.ValueMember = "href";//使用另一种方法会失效!!!
cbSortName.SelectedIndexChanged += cbSortNameEvent; //绑定完了重新注册事件
cbSortName.SelectedIndex = 0;
}));
[/quote]
这样解决了绑定数据源触发SelectedIndexChanged事件,但是这个错误还在,好像不是这个引起的。。。。
[/quote]

button事件要这样写,不要同时在这里加载子项,又在indexchanged里绑定子项。


private void btnStart_Click(object sender, EventArgs e)
{
Thread thread = new Thread(() =>
{
loadSort();
//loadNovelName();
//loadNovelContent();
});
thread.Start();
}
  • 打赏
  • 举报
回复
引用 5 楼 正怒月神 的回复:
改成
this.Invoke(new Action(()=> {
cbSortName.DataSource = sorts;
                cbSortName.Enabled = true;
                cbSortName.DisplayMember = "sortName";
                cbSortName.ValueMember = "href";//使用另一种方法会失效!!!
                cbSortName.SelectedIndex = 0;
            }));
试试看
也不行
正怒月神 2020-08-24
  • 打赏
  • 举报
回复
改成
this.Invoke(new Action(()=> {
cbSortName.DataSource = sorts;
                cbSortName.Enabled = true;
                cbSortName.DisplayMember = "sortName";
                cbSortName.ValueMember = "href";//使用另一种方法会失效!!!
                cbSortName.SelectedIndex = 0;
            }));
试试看
  • 打赏
  • 举报
回复
引用 1 楼 icoolno1 的回复:
返回的sorts是空的吧。
sorts里面的数据正常
  • 打赏
  • 举报
回复
引用 2 楼 glen30 的回复:
改成下面的试试看呢? cbSortName.Invoke(new MethodInvoker(delegate { cbSortName.SelectedIndex = -1; cbSortName.Text = "正在加载...."; cbSortName.Enabled = false; })); 不能用this吧?
试了一下也不行
鸡窝里的毛 2020-08-24
  • 打赏
  • 举报
回复
引用 13 楼 icoolno1 的回复:
[quote=引用 12 楼 icoolno1 的回复:][quote=引用 11 楼 cah黎明就在眼前 的回复:][quote=引用 9 楼 icoolno1 的回复:]
试了一下不行,它这个虽然出错了但捕获不到异常信息,而且程序能够运行起来

你这程序建了几个线程啊,除了Button事件里,是不是还有其它线程。

如果多个线程在跑,控件被其它线程改动了,会导致当前线程无法确切的属性值,就会报这个错。[/quote]

看到了,错误原因就在这,绑定的时候肯定会触发这个事件的,而ButtonClick还没完成,于是冲突了:

private void cbSortName_SelectedIndexChanged(object sender, EventArgs e)
{


Thread thread = new Thread(()=> { loadNovelName(); });
thread.Start();
//loadNovelName();
}
[/quote]

试试改成这样,把控件的事件移除掉,改成代码中手动注册,比如:


EventHandler cbSortNameEvent;
EventHandler cbNovelNameEvent;

public textSpider()
{
InitializeComponent();
cbSortNameEvent = new EventHandler(cbSortName_SelectedIndexChanged);//实例化事件
cbNovelNameEvent = new EventHandler(cbNovelName_SelectedIndexChanged);//实例化事件,当然其它事件依葫芦画瓢,这里举只两个例子作为参考。
}

//
cbSortName.Invoke(new MethodInvoker(delegate
{
cbSortName.SelectedIndex = -1;
cbSortName.Text = "正在加载....";
cbSortName.Enabled = false;

cbSortName.SelectedIndexChanged -= cbSortNameEvent;//防止绑定过程中触发事件
}));

//省略

this.Invoke(new Action(() => {
cbSortName.DataSource = sorts;
cbSortName.Enabled = true;
cbSortName.DisplayMember = "sortName";
cbSortName.ValueMember = "href";//使用另一种方法会失效!!!
cbSortName.SelectedIndexChanged += cbSortNameEvent; //绑定完了重新注册事件
cbSortName.SelectedIndex = 0;
}));
  • 打赏
  • 举报
回复
引用 13 楼 icoolno1 的回复:
[quote=引用 12 楼 icoolno1 的回复:][quote=引用 11 楼 cah黎明就在眼前 的回复:][quote=引用 9 楼 icoolno1 的回复:] 试了一下不行,它这个虽然出错了但捕获不到异常信息,而且程序能够运行起来
你这程序建了几个线程啊,除了Button事件里,是不是还有其它线程。 如果多个线程在跑,控件被其它线程改动了,会导致当前线程无法确切的属性值,就会报这个错。[/quote] 看到了,错误原因就在这,绑定的时候肯定会触发这个事件的,而ButtonClick还没完成,于是冲突了:

private void cbSortName_SelectedIndexChanged(object sender, EventArgs e)
        {
             
             
            Thread thread = new Thread(()=> { loadNovelName(); });
            thread.Start();
            //loadNovelName();
        }
[/quote] 哦,明白了,非常感谢,但是loadSort中的

this.Invoke(new Action(() => {
                cbSortName.SelectedIndex = -1;
                cbSortName.Text = "正在加载....";
                cbSortName.Enabled = false;
            }));
这里的cbSortName.SelectedIndex = -1; cbSortName.Text = "正在加载....";也出现了这样的异常,它们是怎么引起的呢,我点击按钮它首先是开启一个线程运行这个方法,还没有给它绑定数据源,因此也不会触发SelectedIndexChanged事件,为什么也会报错
鸡窝里的毛 2020-08-24
  • 打赏
  • 举报
回复
引用 12 楼 icoolno1 的回复:
[quote=引用 11 楼 cah黎明就在眼前 的回复:][quote=引用 9 楼 icoolno1 的回复:]
试了一下不行,它这个虽然出错了但捕获不到异常信息,而且程序能够运行起来

你这程序建了几个线程啊,除了Button事件里,是不是还有其它线程。

如果多个线程在跑,控件被其它线程改动了,会导致当前线程无法确切的属性值,就会报这个错。[/quote]

看到了,错误原因就在这,绑定的时候肯定会触发这个事件的,而ButtonClick还没完成,于是冲突了:

private void cbSortName_SelectedIndexChanged(object sender, EventArgs e)
{


Thread thread = new Thread(()=> { loadNovelName(); });
thread.Start();
//loadNovelName();
}
鸡窝里的毛 2020-08-24
  • 打赏
  • 举报
回复
引用 11 楼 cah黎明就在眼前 的回复:
[quote=引用 9 楼 icoolno1 的回复:]
试了一下不行,它这个虽然出错了但捕获不到异常信息,而且程序能够运行起来

你这程序建了几个线程啊,除了Button事件里,是不是还有其它线程。

如果多个线程在跑,控件被其它线程改动了,会导致当前线程无法确切的属性值,就会报这个错。
  • 打赏
  • 举报
回复
引用 9 楼 icoolno1 的回复:
[quote=引用 8 楼 cah黎明就在眼前 的回复:][quote=引用 7 楼 icoolno1 的回复:][quote=引用 4 楼 cah黎明就在眼前 的回复:][quote=引用 1 楼 icoolno1 的回复:]返回的sorts是空的吧。
sorts里面的数据正常[/quote] 被你后边的内容带偏了,错误是AccessibilityObject引用异常。看看哪里设置了控件的这个属性,或者查一下异常里边有没有InnerException,从InnerException找具体出错位置。[/quote] 没有设置过控件的这个属性,而且cbSortName这个控件好多地方都出现了这个异常。这个异常里的InnerException怎么查看啊,没找到。。。刚学C#没多久还不太会 [/quote] try{}catch(Exception e)一下,单点进去,Exception有innerException[/quote] 试了一下不行,它这个虽然出错了但捕获不到异常信息,而且程序能够运行起来
  • 打赏
  • 举报
回复
不知道啥原因,线程这方面还不太懂,把所有代码都贴出来给大佬们看看吧

using HtmlAgilityPack;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace BaiduSpider
{
    public partial class textSpider : Form
    {
        public textSpider()
        {
            InitializeComponent();
        }
        private string url = "https://www.biquge.com";
        private HtmlAgilityPack.HtmlDocument ReturnHD(string url)//返回该地址对应的html
        {
            HtmlWeb htmlWeb = new HtmlWeb();
            htmlWeb.OverrideEncoding = Encoding.GetEncoding("gbk");//设置解析字符集
            return htmlWeb.Load(url);
        }

        private HtmlAgilityPack.HtmlDocument ReturnHD1(string url)//返回该地址对应的html
        {
            HtmlWeb htmlWeb = new HtmlWeb();
            htmlWeb.OverrideEncoding = Encoding.GetEncoding("utf-8");//设置解析字符集
            return htmlWeb.Load(url);
        }


        private void textSpider_Load(object sender, EventArgs e)
        {
            
        }

        string contentsUrl;
        private void loadNovelContent()//加载当前小说的所有章节
        {
            this.Invoke(new Action(() => {
                cbContents.SelectedIndex = -1;
                cbContents.Text = "正在加载....";
                cbContents.Enabled = false;
                if(cbNovelName.SelectedValue != null)
                {
                    contentsUrl = url + cbNovelName.SelectedValue.ToString();
                }
                
            }));

            ArrayList cts = new ArrayList();
            HtmlAgilityPack.HtmlDocument htmlDocument = ReturnHD1(contentsUrl);
            HtmlNodeCollection contents = htmlDocument.DocumentNode.SelectNodes("//dd");
            if (contents.Count > 12)
            {
                for(int i = 12; i < contents.Count; i++)
                {
                    string href = contents[i].ChildNodes[1].Attributes["href"].Value;
                    string content = contents[i].ChildNodes[1].InnerHtml;
                    cts.Add(new contents(href, content));
                }
            }
            cbContents.DataSource = cts;
            this.Invoke(new Action(()=> {
                cbContents.DisplayMember = "content";
                cbContents.ValueMember = "href";
                cbContents.SelectedIndex = 0;
                cbContents.Enabled = true;
            }));

        }
        
        string sortUrl;
        private void loadNovelName()//加载当前分类下的小说名称
        {
            //Action action = new Action();
            
            
            this.Invoke(new Action(()=> {
                cbNovelName.SelectedIndex = -1;
                cbNovelName.Text = "正在加载....";
                cbNovelName.Enabled = false;
                this.sortUrl = cbSortName.SelectedValue.ToString();
            }));

            if(sortUrl == "BaiduSpider.novelSort")//防止初始化cbSortName而引起的cbSortName_SelectedIndexChanged事件
            {
                return;
            }
            HtmlAgilityPack.HtmlDocument htmlDocument = ReturnHD(sortUrl);
            HtmlNodeCollection booksNode = htmlDocument.DocumentNode.SelectNodes("//span[@class = 's2']");
            ArrayList books = new ArrayList();  
            if(booksNode == null||booksNode.Count == 0)
            {
                return;
            }
            foreach(HtmlNode n in booksNode)
            {
                string href = n.ChildNodes[0].Attributes["href"].Value;
                string sortName = n.ChildNodes[0].InnerHtml.Trim();
                books.Add(new novelSort(sortName, href));
            }
            //MessageBox.Show("url = " + sortUrl);
            cbNovelName.DataSource = books;
            this.Invoke(new Action(()=> {
                cbNovelName.DisplayMember = "sortName";//名称必须和novelSort中对应
                cbNovelName.ValueMember = "href";
                cbNovelName.SelectedIndex = 0;
                cbNovelName.Enabled = true;
            }));
            
        }

        private void loadSort()//加载小说分类
        {
            //cbSortName.Invoke(new Action(() => {
            //    cbSortName.SelectedIndex = -1;
            //    cbSortName.Text = "正在加载....";
            //    cbSortName.Enabled = false;
            //}));
            cbSortName.Invoke(new MethodInvoker(delegate
            {
                cbSortName.SelectedIndex = -1;
                cbSortName.Text = "正在加载....";
                cbSortName.Enabled = false;
            }));
            HtmlAgilityPack.HtmlDocument htmlDocument = ReturnHD(url);
            HtmlNode sortNode = htmlDocument.DocumentNode.SelectSingleNode("//div[@class = 'nav']");
            HtmlNodeCollection listSort = sortNode.ChildNodes[1].ChildNodes;
            ArrayList sorts = new ArrayList();
            for(int i = 0,j=0;i < listSort.Count; i++)
            {
                if (listSort[i].ChildNodes.Count > 0) {
                    j++;
                    if (j > 2) { 
                        HtmlNode node = listSort[i].ChildNodes[0];
                        string sortName = node.InnerHtml.Trim();
                        string href = node.Attributes["href"].Value;
                        sorts.Add(new novelSort(sortName, href));
                        //novelSort novel = new novelSort(sortName, href);
                        //cbSortName.Items.Add(novel);
                    }
                }

            }
            
            //Control.CheckForIllegalCrossThreadCalls = false;
            this.Invoke(new Action(()=> {
                cbSortName.DataSource = sorts;
                cbSortName.Enabled = true;
                cbSortName.DisplayMember = "sortName";
                cbSortName.ValueMember = "href";//使用另一种方法会失效!!!
                cbSortName.SelectedIndex = 0;
            }));
            
            
        }

        private void cbSortName_SelectedIndexChanged(object sender, EventArgs e)
        {
            
            
            Thread thread = new Thread(()=> { loadNovelName(); });
            thread.Start();
            //loadNovelName();
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            Thread thread = new Thread(() => {
                loadSort();
                loadNovelName();
                loadNovelContent();
            });
            thread.Start();
        }

        private void cbNovelName_SelectedIndexChanged(object sender, EventArgs e)
        {
            Thread thread = new Thread(() => { loadNovelContent(); });
            thread.Start();
        }
    }
}

之前还有个问题就是我在窗体加载事件中开启线程执行 Thread thread = new Thread(() => { loadSort(); loadNovelName(); loadNovelContent(); }); thread.Start(); 时出现Invoke or BeginInvoke cannot be called on a control until the window handle has been created.错误,网上说这个是窗体还没有建立起来是不能调用Invoke方法的,所以我改成了采用按钮点击事情去执行。顺便问一下如果要在窗口加载中去开启线程执行应该怎么写才能不出现这样错误呢
鸡窝里的毛 2020-08-24
  • 打赏
  • 举报
回复
引用 8 楼 cah黎明就在眼前 的回复:
[quote=引用 7 楼 icoolno1 的回复:][quote=引用 4 楼 cah黎明就在眼前 的回复:][quote=引用 1 楼 icoolno1 的回复:]返回的sorts是空的吧。

sorts里面的数据正常[/quote]

被你后边的内容带偏了,错误是AccessibilityObject引用异常。看看哪里设置了控件的这个属性,或者查一下异常里边有没有InnerException,从InnerException找具体出错位置。[/quote]
没有设置过控件的这个属性,而且cbSortName这个控件好多地方都出现了这个异常。这个异常里的InnerException怎么查看啊,没找到。。。刚学C#没多久还不太会
[/quote]

try{}catch(Exception e)一下,单点进去,Exception有innerException
  • 打赏
  • 举报
回复
引用 7 楼 icoolno1 的回复:
[quote=引用 4 楼 cah黎明就在眼前 的回复:][quote=引用 1 楼 icoolno1 的回复:]返回的sorts是空的吧。
sorts里面的数据正常[/quote] 被你后边的内容带偏了,错误是AccessibilityObject引用异常。看看哪里设置了控件的这个属性,或者查一下异常里边有没有InnerException,从InnerException找具体出错位置。[/quote] 没有设置过控件的这个属性,而且cbSortName这个控件好多地方都出现了这个异常。这个异常里的InnerException怎么查看啊,没找到。。。刚学C#没多久还不太会
加载更多回复(3)

111,125

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧