我先用正则分析,得到了100多个URL.
100多个url我需要用10个线程分别采集
结果显示在一个 ListBox里面,比如
线程1开始采集http://www.web1.com
线程2开始采集http://www.web2.com
........
线程2采集http://www.web2.com结束
线程1采集http://www.web1.com结束
.........
备注:不能重复采集哦,请会的兄弟写点核心的代码或者思想给我...还可以再加分...
100多个url我需要用10个线程分别采集
结果显示在一个 ListBox里面,比如
线程1开始采集http://www.web1.com
线程2开始采集http://www.web2.com
........
线程2采集http://www.web2.com结束
线程1采集http://www.web1.com结束
.........
备注:不能重复采集哦,请会的兄弟写点核心的代码或者思想给我...还可以再加分...
Hello
********************************[/align]
private void Start()
{
string[] urls = {"http://www.web1.com", "http://www.web2.com", ...}; Queue<string> tasks = new Queue<string>(urls);
for (int i = 0; i < 10; i++)
{
ThreadPool.QueueUserWorkItem(this.Worker, tasks);
}
}private void Worker(object state)
{
Queue<string> tasks = state as Queue<string>;
while (true)
{
string url = null;
lock (tasks) //<---
{
if (tasks.Count == 0) return;
url = tasks.Dequeue();
} string result = Process(url);
ShowResultInListbox(result);
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;namespace Test
{
class Program
{
//手动通知
private static ManualResetEvent ent = new ManualResetEvent(false);
//自动通知
//private static AutoResetEvent are = new AutoResetEvent(false);
//信号控制
//static Semaphore sema = new Semaphore(4, 4);
public static void Main()
{
for (int i = 1; i <= 3; i++)
{
//信号申请
//if (sema.WaitOne())
{
Boy sender = new Boy(ent,i);
Thread th = new Thread(new ThreadStart(sender.SendFlower));
th.Start();
//ent.WaitOne(); //等待工作
//are.WaitOne();//等待工作
ent.WaitOne();//等待工作
}
//else
{
// Console.WriteLine("信号已满!请等待!");
}
ent.Reset();//重置阻塞
}
Console.WriteLine("收到了吧,花是我送嘀:)\r\n\r\n");
Console.ReadLine();
} } public class Boy
{
ManualResetEvent ent;
AutoResetEvent are;
Semaphore sema;
int pid;
public Boy(Semaphore s,int PId)
{
sema = s;
pid=PId;
}
public Boy(AutoResetEvent are, int PId)
{
this.are = are;
pid = PId;
} public Boy(ManualResetEvent ent, int PId)
{
this.ent = ent;
pid = PId;
}
public void SendFlower()
{
try
{
Console.WriteLine("正员工{0}在送花的途中",pid);
for (int i = 0; i < 4; i++)
{
Thread.Sleep(200);
Console.Write(pid.ToString()+".");
}
Console.WriteLine("\r\n花已经送到MM手中了,boss");
Thread.Sleep(200);
}
catch (Exception ex)
{ }
finally
{
//sema.Release();
}
//are.Set(); //通知阻塞程序,这里的效果相当于 ManualResetEvent的Set()方法+Reset()方法
ent.Set();
}
}
}你把所有关于Semaphore的注释取消,把所有关于ManualResetEvent的内容注释掉。估计就是你想要的那个效果了。
// 下载线程类 MyDownload.csusing System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Net;
using System.ComponentModel;namespace ConsoleApplication1
{
public class MyDownload
{
public class DownloadEventArgs : EventArgs
{
public string Url { get; set; }
public DownloadEventArgs()
{
}
public DownloadEventArgs(string url)
{
this.Url = url;
}
}
const int MaxThread = 10;
Queue<string> m_urls; Thread[] m_threads;
public event EventHandler<DownloadEventArgs> DownloadFileCompleted; public MyDownload(string[] urls)
{
m_urls = new Queue<string>(urls);
} internal void Start()
{
m_threads = new Thread[MaxThread];
for (int i = 0; i < m_threads.Length; i++)
{
m_threads[i] = new Thread(new ThreadStart(DownloadThread));
m_threads[i].Start();
}
} private void DownloadThread()
{
WebClient web = new WebClient();
string url = null, filename=null;
while (true)
{
lock (((ICollection)m_urls).SyncRoot)
{
if (m_urls.Count == 0)
{
return;
}
url = m_urls.Dequeue();
}
Console.WriteLine("start download: "+url);
try
{
filename = GetFileName(url);
web.DownloadFile(url, filename);
if (DownloadFileCompleted != null)
{
DownloadFileCompleted(this, new DownloadEventArgs(url));
}
}
catch (Exception ex)
{
Console.WriteLine("download error: " + ex.Message);
}
}
} private string GetFileName(string url)
{
return url.Replace('?', '_').Replace(':', '_') + ".htm";
} }
}// 调用
static void Main(string[] args)
{
MyDownload myD = new MyDownload(new string[] { "http://www.google.cn", "http://www.baidu.com" });
myD.DownloadFileCompleted += new EventHandler<MyDownload.DownloadEventArgs>(myD_DownloadFileCompleted);
myD.Start();
}
1 多线程访问队列时,要做好同步管理
2 注意不要重复下载,会导致文件名重复出错
3 在window form 的UI 中,处理线程事件时,要用Invoke
4 应该要提供终止的方法