我做了一个很简单的抓取网页的程序,将抓取到的页面显示在RichTextBox中,抓取的语句和方法我把它定义在了WebHtml类中,通过给这个类的实例对象赋值(把参数传给它)和它的GetHtml()方法来获得页面,GetHtml()返回抓到的网页字符串,并把它存在MainForm中的RichTextBox中。
代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Net;
using System.Net.Sockets;namespace www
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
} private void btnCancel_Click(object sender, EventArgs e)
{
this.backgroundWorker.CancelAsync(); } private void btnLogin_Click(object sender, EventArgs e)
{
this.backgroundWorker.RunWorkerAsync();
btnLogin.Enabled = false;
btnCancel.Enabled = true;
toolStripStatusLabel.Text = "正在抓取";
while (this.backgroundWorker.IsBusy)
{
Application.DoEvents();
}
btnLogin.Enabled = true;
} private void MainForm_Load(object sender, EventArgs e)
{
} private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
} private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
MessageBox.Show("你已经取消了抓取!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
else if (e.Error != null)
{
MessageBox.Show("抓取过程发生了错误", "失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
toolStripStatusLabel.Text = "抓取完成";
}
btnLogin.Enabled = true;
btnCancel.Enabled = false;
} private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
//准备初始数据
string url = "http://xxx.xxx.xxx";
postData += "site_id=13&";
postData += "data=20090128&";
postData += "ast=13&";
postData += "dts=13&";
postData = postData + "id=" + textUsername.Text + '&';
postData = postData + "pwd=" + textPassword.Text;
//生成对象实例,将参数提交给对象webHtml
WebHtml webHtml = new WebcHtml(url, postData);
//将抓取的网页在richTextBox中显示
richTextBox.Text=weHtml.GetHtml(); <=====就是这句出错了
}
}
}程序能通过编译并运行,只是执行到最后一步时出错了,提示是“线程间操作无效,从不是创建控件"richTextBox的线程访问它”,我确定不是我代码输错了,因为我如果不用BackgroundWork,直接将语句写在btnLogin的事件中就可以正常运行。
在此想请教2个问题:
1、我的程序哪里错了?
2、在通过HttpWepRequest抓取网页的过程中,就算点取消是不是中止不了?
代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Net;
using System.Net.Sockets;namespace www
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
} private void btnCancel_Click(object sender, EventArgs e)
{
this.backgroundWorker.CancelAsync(); } private void btnLogin_Click(object sender, EventArgs e)
{
this.backgroundWorker.RunWorkerAsync();
btnLogin.Enabled = false;
btnCancel.Enabled = true;
toolStripStatusLabel.Text = "正在抓取";
while (this.backgroundWorker.IsBusy)
{
Application.DoEvents();
}
btnLogin.Enabled = true;
} private void MainForm_Load(object sender, EventArgs e)
{
} private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
} private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
MessageBox.Show("你已经取消了抓取!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
else if (e.Error != null)
{
MessageBox.Show("抓取过程发生了错误", "失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
toolStripStatusLabel.Text = "抓取完成";
}
btnLogin.Enabled = true;
btnCancel.Enabled = false;
} private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
//准备初始数据
string url = "http://xxx.xxx.xxx";
postData += "site_id=13&";
postData += "data=20090128&";
postData += "ast=13&";
postData += "dts=13&";
postData = postData + "id=" + textUsername.Text + '&';
postData = postData + "pwd=" + textPassword.Text;
//生成对象实例,将参数提交给对象webHtml
WebHtml webHtml = new WebcHtml(url, postData);
//将抓取的网页在richTextBox中显示
richTextBox.Text=weHtml.GetHtml(); <=====就是这句出错了
}
}
}程序能通过编译并运行,只是执行到最后一步时出错了,提示是“线程间操作无效,从不是创建控件"richTextBox的线程访问它”,我确定不是我代码输错了,因为我如果不用BackgroundWork,直接将语句写在btnLogin的事件中就可以正常运行。
在此想请教2个问题:
1、我的程序哪里错了?
2、在通过HttpWepRequest抓取网页的过程中,就算点取消是不是中止不了?
{
private delegate void FlushClient();//代理
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Thread thread = new Thread(CrossThreadFlush);
thread.IsBackground = true;
thread.Start();
} private void CrossThreadFlush()
{
while (true)
{
//将sleep和无限循环放在等待异步的外面
Thread.Sleep(1000);
ThreadFunction();
}
}
private void ThreadFunction()
{
if (this.textBox1.InvokeRequired)//等待异步
{
FlushClient fc = new FlushClient(ThreadFunction);
this.Invoke(fc);//通过代理调用刷新方法
}
else
{
this.textBox1.Text = DateTime.Now.ToString();
}
}
}文章来自学IT网:http://www.xueit.com/html/2009-03/21_903_00.html
直接在RunWorkerCompleted这里面赋值;