我想实现一个这样的功能,一个类似blog或bbs的网站,每一页从上倒下有25条文章连接,每个连接都连接到一个单独的文章内容页,这个网站共有100页。也就是共有2500条文章。
winform,我想用多线程,点一个按钮,然后先下载其文章列表第一页,然后找出其各文章列表页的地址,然后先取第一文章列表页的内容,找到这页25条文章的连接地址,这时启动25个线程用于下载这写文章存入数据库,同时另有一个线程会转到第二个文章列表页取该页的文章地址,那25个线程读完了就依次从读文章列表页的线程读出的第二页25条文章地址开始下载该页,这里有个问题,就是如果读取列表页的线程没有读完,比如只读了18个地址,则那25个线程则只18个从追加的地址下载,另7个则继续等待,如果读取页列表的线程已经读取了好几页几十条连接了,则那写线程全力下载,就是说总有25个线程在排队等待着地址列表有新追加的地址,没有新的则等待,有一个新的就让一个排队等待的线程开始下载他,这样如此协调的把这100页2500条文章全存进数据库。
==================
下载、找连接、存数据库这些都不用说了,关键是多线程部分,实在没思路如何协调那些线程,如有做过这类型程序的给个代码,如果没有代码给个思路也许,不知在第二个线程控制第三个线程可行么,最好还是个例子或文章,谢了各位。

解决方案 »

  1.   

    先不用考虑25个线程之多了。主要分为两中线程:1.读取文章列表的线程
                      2.下载文章的线程他们两协调可以通过数据库来或者其他的静态变量。比如说有个列表字段,还有一个表示其状态的:
          
              文章列表          下载状态(0:表示未下载,1:表示下载了)
    www.abc.com/topic1.html        0
    www.abc.com/topic2.html        0
    www.abc.com/topic3.html        1
                ...                ...下载线程判断下载状态,读取文章列表内的地址进行下载,并且修改下载状态。
      

  2.   

    如果要使用线程池,msdn对它有很多sample,你可以参看一下,基本上都在
    vs安装目录下<SDK>v1.1\Samples\Technologies\Threading\这个目录
      

  3.   

    fangxinggood(JustACoder) 这样的话就得先把所有文章连接全下载下来啊,那不合要求啊,我需要的是下载了几个连接,就让几个闲置线程来下载改连接的文章。Knight94(愚翁) 
    我的是2005,sdk的sample里只有asp.net和数据库的没有关于c#的线程的winform的,而且msdn的线程池例子我看了,和直接用线程一样啊,完成的都是同样地工作。没有关于不同任务间相互协调的。请各位还是给例子吧或者这类文章吧
      

  4.   

    to 我的是2005,sdk的sample里只有asp.net和数据库的没有关于c#的线程的winform的,而且msdn的线程池例子我看了,和直接用线程一样啊,完成的都是同样地工作。没有关于不同任务间相互协调的。在vs2005的msdn中查看threadpool这个类的samples,
    选择“Threadpools technology sample”这个例子,采用异步回调的方法
    大致如下:
    using System;
    using System.Threading;
    class App {
       public static void Main() {
          Console.WriteLine("Main thread: Queuing an asynchronous operation.");
          AutoResetEvent asyncOpIsDone = new AutoResetEvent(false);
          ThreadPool.QueueUserWorkItem(new WaitCallback(MyAsyncOperation), asyncOpIsDone);      Console.WriteLine("Main thread: Performing other operations.");
          // ...      Console.WriteLine("Main thread: Waiting for asynchronous operation to complete.");
          asyncOpIsDone.WaitOne();
       }
       // The callback method's signature MUST match that of a System.Threading.WaitCallback 
       // delegate (it takes an Object parameter and returns void)
       static void MyAsyncOperation(Object state) {
          Console.WriteLine("WorkItem thread: Performing asynchronous operation.");
          // ...
          Thread.Sleep(5000); // Sleep for 5 seconds to simulate doing work      // Signal that the async operation is now complete.
          ((AutoResetEvent)state).Set();
       }
    }
      

  5.   

    fangxinggood(JustACoder) 这样的话就得先把所有文章连接全下载下来啊,那不合要求啊,我需要的是下载了几个连接,就让几个闲置线程来下载改连接的文章。=======================================怎么会呢?下载完一个文章连接,就往数据库里增加一条数据,下载内容的线程取未下载的文章进行下载...假设初始状态下,数据库里一条记录也没有,那么自然是下载内容的线程全部闲置了。如果这时候有一个文章的连接下载完了,那么就往数据库里增加一条数据,下载内容的线程通过sql取出下载完连接的数据进行下载...两种线程各干各的,一个往数据库里放,一个往数据库里取,互不影响的。
      

  6.   

    同意楼上,楼主意思的是不是下面这个意思
              文章列表          下载状态(0:表示未下载,1:正在下载了 2:下载完了 3:找连接ing 4:找连接完成)
    www.abc.com/topic1.html        0
    www.abc.com/topic2.html        0
    www.abc.com/topic3.html        1
    这样已经下载过的就不会再下载了,也不会重复找连接
      

  7.   

    可以用一个信号量来协调他们及建立一个量用于存储当前已经写入的链接,用arraylist也可以然后写一个函数,循环读arraylist的内容,如果为空则阻止,直到信号量的值大于1为止
      

  8.   

    感觉 .net弄的这个threadpool使着不爽没java的感觉顺手.就觉得别扭在这耽误好长时间拉.哎!
      

  9.   

    告诉你我的解决办法, 一个先进先出队列保存所有网页提取的URL地址, 一个主线程不段从队列中提取URL并从队列中删除之,启动一个新的线程(线程池),用这个新线程去读取刚取出的URL地址文章,并从文章中提取URL地址放到先前那个队列中,---->哈哈,简单有效.