zoukankan      html  css  js  c++  java
  • C#动态多线程实例

    在C#中用多线程并不难实现。它有一个命名空间:System.Threading,提供了多线程的支持。
      

    要开启一个新线程,须要以下的初始化:

    ThreadStart startDownload = new ThreadStart( DownLoad );

    //线程起始设置:即每个线程都执行DownLoad(),注意:DownLoad()必须为不带有参数的方法

    Thread downloadThread = new Thread( startDownload ); //实例化要开启的新类

    downloadThread.Start();//开启线程

    由于线程起始时启动的方法不能带有参数,这就为多线程共享资源添加了麻烦。不过我们可以用类级变量(当然也可以使用其它方法,笔者以为此方法最简单易用)来解决这个问题。知道开启多线程下载的方法后,大家可能会发生几个疑问:

    1.如何操纵线程的数量?

    2.如何防止多线程下载同一网页?

    3.如何判断线程结束?

    4.如何操纵线程结束?

    下面就这几个问题提出解决方法:

    1.线程数量我们可以通过for循环来实现,就如同当年初学编程的打点程序一样。

    譬如已知用户指定了n(它是一个int型变量)个线程吧,可以用如下方法开启五个线程。

    Thread[] downloadThread;

    //声名下载线程,这是C#的优势,即数组初始化时,不需要指定其长度,可以在使用时才指定。

    这个声名应为类级,这样也就为其它方法控件它们提供了可能

    ThreadStart startDownload = new ThreadStart( DownLoad );

    //线程起始设置:即每个线程都执行DownLoad()

    downloadThread = new Thread[ n ];//为线程申请资源,确定线程总数

    for( int i = 0; i < n; i++ )//开启指定数量的线程数

    {

    downloadThread[i] = new Thread( startDownload );//指定线程起始设置

    downloadThread[i].Start();//逐个开启线程

    }

    好了,实现控制开启线程数是不是很简单啊?

    2.下面出现的一个问题:所有的线程都调用DonwLoad()方法,这样如何避免它们同时下载同一个网页呢?

    这个问题也好解决,只要树立一下Url地址表,表中的每个地址只容许被一个线程申请即可。具体实现:

    可以利用数据库,树立一个表,表中有四列,其中一列专门用于存储Url地址,另外两列分别存放地址对应的线程以及该地址被申请的次数,最后一列存放下载的内容。(当然,对应线程一列不是必要的)。当有线程申请后,将对应线程一列设定为当前线程编号,并将是否申请过一列设置为申请一次,这样,别的线程就无法申请该页。要是下载成功,则将内容存入内容列。要是不成功,内容列仍为空,作为是否再次下载的依据之一,如果反复不成功,则进程将于达到重试次数(对应当地址被申请的次数,用户可设)后,申请下一个Url地址。好了,这样就解决了多线程中,线程冲突。当然,去重问题也可以在C#语言内解决,只根建立一个临时文件(文本就可以),保存所有的Url地址,差对它们设置相应的属性即可,但查找效率可能不及数据库快。

    3.线程结束是很难判断的,因为它总是在查找新的链接。用者认为可以假设:线程重复N次以后还是没有能申请到新的Url地址,那么可以觉得它已经下载完了所有链接。主要代码如下:

    string url = "";

    int times = 0;

    while ( url == "" )//要是没有找到符合条件的记录,则不断地寻觅符合条件的记录

    {

    url = getUrl.GetAUrl( …… );//调用GetAUrl方法,试图得到一个url值

    if ( url == "" )//要是没有找到

    {

    times ++;//尝试次数自增

    continue; //进行下一次尝试

    }

    if ( times > N ) //要是已经尝试够了次数,则退出进程

    {

    downloadThread[i].Abort; //退出进程

    }

    else//如果没有尝试够次数

    {

    Times = 0; //尝试次数归零处理

    }

    //进行下一步针对得到的Url的处理

    }

    4.这个问题相对简单,因为在问题一中已经提议,将线程声名为类级数组,这样就很易于操纵。只要用一个for循环即可结束。代码如下:

    for( int i = 0; i < n; i++ )//关闭指定数量n的线程数

    {

    downloadThread[i].Abort();//逐个关闭线程

    }

    好了,一个多线程的C#程序就这样完成了,在C#面前,它的实现本来如此简单。

  • 相关阅读:
    PAT 1010. 一元多项式求导 (25)
    PAT 1009. 说反话 (20) JAVA
    PAT 1009. 说反话 (20)
    PAT 1007. 素数对猜想 (20)
    POJ 2752 Seek the Name, Seek the Fame KMP
    POJ 2406 Power Strings KMP
    ZOJ3811 Untrusted Patrol
    Codeforces Round #265 (Div. 2) 题解
    Topcoder SRM632 DIV2 解题报告
    Topcoder SRM631 DIV2 解题报告
  • 原文地址:https://www.cnblogs.com/houzuofeng/p/3253131.html
Copyright © 2011-2022 走看看