望版主及各位C#高手,进来帮我看一下,是关于多线程,以及webbrower控件,还DocumentCompleted事件执行的相关问题(代码很简单)

asimplefire 2010-06-04 03:50:44
最近自己在写一个小工具,是采用多线程通过代理IP去采集某一个网站内容。软件功能很简单,winform当中有一个gridview列表,每一行记录是一个任务。现需要让多个任务同时运行。一个线程托管一个任务运行。

private void btn_SimulationClick_Click(object sender, EventArgs e)
{
Thread thread = new Thread(new ThreadStart(ExecuteFormTask));
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
public void ExecuteFormTask()
{
foreach(DataGridViewRow row in this.taskList.SelectedRows) //winform有一个Gridview列表,显示任务
{
string taskid = row.Cells[11].Value.ToString();
this.Invoke(new DelegateExecuteOneTaskByTaskId(ExecuteOneTaskByTaskId), new Object[] { taskid });
}
}
public delegate void DelegateExecuteOneTaskByTaskId(string taskId);
public void ExecuteOneTaskByTaskId(string taskId)
{
//this.Invoke(new LoadExcuting(InitExcuteTask), new Object[] { taskId });
for (int i = 0; i < ProxyIpTable.Rows.Count; i++)
{
string sql = "select * from [task] where [task_id]=" + taskId;
DataTable dt = PPTech.ESP.DataProvider.ExecuteSql.FetchDataTable(sql);//查询该记录信息
string mainKey = dt.Rows[0]["kw_center"].ToString();
string aboutKey = dt.Rows[0]["kw_end"].ToString();
string ipHost = ProxyIpTable.Rows[i]["HostIP"].ToString() + ":" + ProxyIpTable.Rows[i]["Port"].ToString();//读取IP地址
DateTime dtm = DateTime.Now;
while (DateTime.Now.Subtract(dtm).TotalSeconds < 3) //停顿3秒
{
Application.DoEvents();
}
//lock (this) //考虑到线程同时执行一个函数,不知道lock是否该用到此处???
//{
WebBrowser webbr = new WebBrowser();
RefreshIESettings(ipHost);//设置代理IP
webbr.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webRequsted);
webbr.Navigate("http://www.xx.com/req.aspx?bs=" + getURLEncode(mainKey) + "&wd=" + getURLEncode(aboutKey) + "&taskid=" + taskId);
this.Invoke(new Tab_ItemContent_Add(UpdateTabItemContent), new Object[] { taskId, mainKey });//去即时更新winform,显示"正在执行……"
//}
}
}
//-------------以下都是委托-------------
public delegate void LoadExcuting(string taskId);
public void InitExcuteTask(string taskId)
{
this.tb_item_con1.Text = "正在初始化任务:" + GetTaskNameByTaskId(taskId) + ",请稍后……\r\n";
}
public void webRequsted(object sender, WebBrowserDocumentCompletedEventArgs e)//文档加载完后委托
{
WebBrowser webb = (WebBrowser)sender;
string requestUrl = webb.Url.ToString();
string taskId = Regex.Split(requestUrl, "taskid=", RegexOptions.IgnoreCase)[1].ToString();
UpdateTaskReflashCount(taskId);//完成请求刷新数据库
this.Invoke(new Tab_ItemContent_Loaded_addInfo(UpdateTabItemContent), new Object[] { taskId });//即时更新winform,显示"完成……"
}
public delegate void Tab_ItemContent_Loaded_addInfo(string taskid);//执行任务成功,委托更新tb_item_con1信息
public void UpdateTabItemContent(string taskid)
{
this.tb_item_con1.AppendText("执行任务" + GetTaskNameByTaskId(taskid) + ",成功!\r\n");
this.tb_item_con1.SelectionStart = tb_item_con1.Text.Length;
this.tb_item_con1.ScrollToCaret();
}
public delegate void Tab_ItemContent_Add(string taskId, string mainKey); //委托,更新Tab_item_con1,显示正在刷新信息……
public void UpdateTabItemContent(string taskId, string mainKey)
{
this.tb_item_con1.Text += "正执行任务" + GetTaskNameByTaskId(taskId) + ",准备刷新关键词\"" + mainKey + "\"1次,请稍后……\r\n";
this.tb_item_con1.SelectionStart = tb_item_con1.Text.Length;
this.tb_item_con1.ScrollToCaret();
}

代码在实际运行过程当中会出现几个问题:
1,在选择单个任务的时候,DocumentCompleted事件会触发,但偶儿也不触发。因为在这个事件里,我需要让winform的一个richtextbox能实时显示每次请求的成功情况。
2,在选择多个任务的时候,DocumentCompleted基本上不触发,运行很混乱。
3,为了避免多个线程同时执行一个函数,lock放在哪里最好呢。在我的代码里,lock放控制着DocumentCompleted事件,但效果却不佳,DocumentCompleted也时常不触发。
4,启用多个线程去执行多个任务时,是否不应该用this.Invoke(……)来用委托来处理啊,而应该用Thread 去实例一个对象来执行每一个任务呢?
感谢大家给一些建议啊,谢谢……

...全文
220 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
lovsan6320 2010-06-07
  • 打赏
  • 举报
回复
webclient代理IP

System.Net.WebClient wc = new WebClient();
WebProxy wproxy = new WebProxy(ProxyIpTable.Rows[i]["HostIP"].ToString(), int.Parse(ProxyIpTable.Rows[i]["Port"].ToString()));
wc.DownloadData(url);
wc.OpenReadCompleted += new OpenReadCompletedEventHandler(webRequsted);
fenshm 2010-06-04
  • 打赏
  • 举报
回复
学习~帮顶!
捷哥1999 2010-06-04
  • 打赏
  • 举报
回复
通过代理IP去采集某一个网站内容
可以使用这样的方法,去掉WebBrowser,效率更快:
System.Net.WebClient wc = new System.Net.WebClient();
Byte[] pageData = wc.DownloadData("网页地址");
string s= System.Text.Encoding.Default.GetString(pageData);
threenewbee 2010-06-04
  • 打赏
  • 举报
回复
webbrowser很笨拙,应该用httpwebrequest。
threenewbee 2010-06-04
  • 打赏
  • 举报
回复
webbrowser很笨拙,应该用httpwebrequest。

62,074

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

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