关于客户端发出请求,服务端并发执行多任务(异步方式)的问题,谢谢!
大家好:我有这样一个需求,描述如下:
1. 客户端发送一个请求到服务器端,服务器端需要并发执行多个任务(具体任务有是到多个不同的网站抓取数据)。
2. 但客户端不需要等待服务端把任务全部执行完,当服务端完成一个网站的抓取任务后即可立即返回到客户端,其他抓取任务可以在其他线程中继续执行,执行的结果将写入本机cache,剩下的任务也必须马上执行,因为客户端每隔几秒还会回来请求其他的数据。
3. 客户端每隔几秒发送一次请求到服务端,从本机cache中读取刚才未完成任务的结果,如果读取到说明其他任务也完成了。
我的想法、问题如下:
1. 因为要实现并发,所以首先考虑用.NET的线程池功能。但是根据书上的推荐,线程池的同时开启线程数量是有限制的(CLR 2.0版本中工作线程默认为每CPU 25个)。这样一来,如果用线程池来实现我的需求,很容易就超过了25个这样的限制,以为我在使用线程去别的网站抓取数据的时候,返回的时间是不确定的,最多要一分钟左右,线程很难及时的释放出来。所以随便几个客户在客户端发出请求,我的线程池就满了。请问有什么更好的办法么?
2. 后来考虑了用建立专用线程(new Thread())的办法,但是建立这么多的专用线程,又不调用对应的Thread.Abort(),会有很大的性能问题吧?因为我不知道在主线程返回以后,其他的线程继续执行,改怎么调用相应的Thread.Abort()方法。
我的想法可能很不成熟,大家对这个问题有什么好的办法解决呢?比如消息队列?
希望大家给予我帮助,这个问题对我很重要,谢谢大家了! --------------------编程问答-------------------- 帮顶
学习。 --------------------编程问答-------------------- 帮顶
学习。
--------------------编程问答-------------------- 推荐使用Thread来完成,事实上如果不是死循环,线程函数在执行完成后会自动退出的,比如
void mythread()
{
int a = 0;
for(int i = 0; i < 100; i++) a++;
}
那么通过new Thread(),再Start后,线程函数执行完成后将自动退出,你不需要手动Abort()
我做过和你类似的程序,方法是把每个HTTP请求排队写入一个链表L中,然后开启N(我用的N=100没一点问题)个线程进行数据抓取,每个线程从L表的表头读取URL获取内容并处理后,保存,然后退出函数,这样当前线程数目nCount-1,另外一个主控线程函数负责向链表L尾部中添加新的请求,并实时监控当前线程数目nCount,如果<N且L表不为空则开启新的线程,如果L表中队列过长则考虑增加更多的线程(可能>N),以加快处理。这样就实现了实时处理,实时更新。同时主控线程还应该监控Thread有没有超时的情况,如果超时,那么把处理失败的请求重新加入L表尾部,然后Abort()此线程。 --------------------编程问答-------------------- 推荐使用Thread来完成,事实上如果不是死循环,线程函数在执行完成后会自动退出的,比如
void mythread()
{
int a = 0;
for(int i = 0; i < 100; i++) a++;
}
那么通过new Thread(),再Start后,线程函数执行完成后将自动退出,你不需要手动Abort()
我做过和你类似的程序,方法是把每个HTTP请求排队写入一个链表L中,然后开启N(我用的N=100没一点问题)个线程进行数据抓取,每个线程从L表的表头读取URL获取内容并处理后,保存,然后退出函数,这样当前线程数目nCount-1,另外一个主控线程函数负责向链表L尾部中添加新的请求,并实时监控当前线程数目nCount,如果<N且L表不为空则开启新的线程,如果L表中队列过长则考虑增加更多的线程(可能>N),以加快处理。这样就实现了实时处理,实时更新。同时主控线程还应该监控Thread有没有超时的情况,如果超时,那么把处理失败的请求重新加入L表尾部,然后Abort()此线程。 --------------------编程问答-------------------- 推荐使用Thread来完成,事实上如果不是死循环,线程函数在执行完成后会自动退出的,比如
void mythread()
{
int a = 0;
for(int i = 0; i < 100; i++) a++;
}
那么通过new Thread(),再Start后,线程函数执行完成后将自动退出,你不需要手动Abort()
我做过和你类似的程序,方法是把每个HTTP请求排队写入一个链表L中,然后开启N(我用的N=100没一点问题)个线程进行数据抓取,每个线程从L表的表头读取URL获取内容并处理后,保存,然后退出函数,这样当前线程数目nCount-1,另外一个主控线程函数负责向链表L尾部中添加新的请求,并实时监控当前线程数目nCount,如果<N且L表不为空则开启新的线程,如果L表中队列过长则考虑增加更多的线程(可能>N),以加快处理。这样就实现了实时处理,实时更新。同时主控线程还应该监控Thread有没有超时的情况,如果超时,那么把处理失败的请求重新加入L表尾部,然后Abort()此线程。 --------------------编程问答-------------------- 帮顶,学习。(*^__^*) 嘻嘻…… --------------------编程问答-------------------- 帮顶,学习。o(∩_∩)o... --------------------编程问答-------------------- 推荐使用Thread来完成,事实上如果不是死循环,线程函数在执行完成后会自动退出的,比如
void mythread()
{
int a = 0;
for(int i = 0; i < 100; i++) a++;
}
那么通过new Thread(),再Start后,线程函数执行完成后将自动退出,你不需要手动Abort()
我做过和你类似的程序,方法是把每个HTTP请求排队写入一个链表L中,然后开启N(我用的N=100没一点问题)个线程进行数据抓取,每个线程从L表的表头读取URL获取内容并处理后,保存,然后退出函数,这样当前线程数目nCount-1,另外一个主控线程函数负责向链表L尾部中添加新的请求,并实时监控当前线程数目nCount,如果<N且L表不为空则开启新的线程,如果L表中队列过长则考虑增加更多的线程(可能>N),以加快处理。这样就实现了实时处理,实时更新。同时主控线程还应该监控Thread有没有超时的情况,如果超时,那么把处理失败的请求重新加入L表尾部,然后Abort()此线程。 --------------------编程问答-------------------- 推荐使用Thread来完成,事实上如果不是死循环,线程函数在执行完成后会自动退出的,比如
void mythread()
{
int a = 0;
for(int i = 0; i < 100; i++) a++;
}
那么通过new Thread(),再Start后,线程函数执行完成后将自动退出,你不需要手动Abort()
我做过和你类似的程序,方法是把每个HTTP请求排队写入一个链表L中,然后开启N(我用的N=100没一点问题)个线程进行数据抓取,每个线程从L表的表头读取URL获取内容并处理后,保存,然后退出函数,这样当前线程数目nCount-1,另外一个主控线程函数负责向链表L尾部中添加新的请求,并实时监控当前线程数目nCount,如果<N且L表不为空则开启新的线程,如果L表中队列过长则考虑增加更多的线程(可能>N),以加快处理。这样就实现了实时处理,实时更新。同时主控线程还应该监控Thread有没有超时的情况,如果超时,那么把处理失败的请求重新加入L表尾部,然后Abort()此线程。 --------------------编程问答-------------------- 继续学习 --------------------编程问答-------------------- 一方面,使用自己创建的线程,也就是 New thread(new ThreadStat( someVoid));
另一方面,我比较喜欢使用异步委托模式,也就是写一个代理,使用 BeginInvoke + EndInvoke 的模式,这样,不用管什么时候它返回,返回,自然执行 CallBack 你所指定的回调方法。然后再以某种楼主希望的方式去通知 Client。MSDN在异步模式那几页写的挺清楚的。
另外,不建议无限制开线程,自己最好有个开关能记录开了多少了。 --------------------编程问答-------------------- 抓网页的商业方案很少用一台机器的 --------------------编程问答-------------------- 有点相似,我最近也在做相似的工作.我认为你的需求已经非常清楚了,我建议你从以下几个方面来考虑:
1.采用什么样的方式系统开销最少,而又能达到你的目的.
2.利用什么的技术把你每次获取到数据之后自动返回的客户端,对获取的数据进行处理.
3.考虑客户端主动请求一次,而后服务器完成任务后,发数据给客户端.
4.客户端每隔几秒发送一次请求到服务端 这样的方式太暴力了,要是客户端多几秒中发送请求,这样做是否最好的解决办法.
5.客户端与服务端信息交流的方式怎样最好.
----------------------------------------
1.用到线程
2.用到委托机制
3.用到通讯
4.采用OBSERVER模式
补充:.NET技术 , .NET Framework