在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#面前,它的实现本来如此简单。

C#动态多线程实例的更多相关文章

  1. Java反射机制可以动态修改实例中final修饰的成员变量吗?

    问题:Java反射机制可以动态修改实例中final修饰的成员变量吗? 回答是分两种情况的. 1. 当final修饰的成员变量在定义的时候就初始化了值,那么java反射机制就已经不能动态修改它的值了. ...

  2. Linux多线程实例练习 - pthread_cancel()

    Linux多线程实例练习 - pthread_cancel 1.代码 xx_pthread_cancel.c #include <pthread.h> #include <stdio ...

  3. Linux多线程实例练习 - pthread_exit() 与 pthread_join()

    Linux多线程实例练习 - pthread_exit 与 pthread_join pthread_exit():终止当前线程 void pthread_exit(void* retval); pt ...

  4. Linux多线程实例练习 - pthread_create()

    Linux多线程实例练习 pthread_create():创建一个线程 int pthread_create(pthread_t *tidp, const pthread_attr_t *attr, ...

  5. Java多线程-实例解析

    Java多线程实例 3种实现方法Java中的多线程有三种实现方式:1.继承Thread类,重写run方法.Thread本质上也是一个实现了Runnable的实例,他代表一个线程的实例,并且启动线程的唯 ...

  6. Java Tread多线程(0)一个简单的多线程实例

    作者 : 卿笃军 原文地址:http://blog.csdn.net/qingdujun/article/details/39341887 本文演示,一个简单的多线程实例,并简单分析一下线程. 编程多 ...

  7. 【原创】Kafka Consumer多线程实例续篇

    在上一篇<Kafka Consumer多线程实例>中我们讨论了KafkaConsumer多线程的两种写法:多KafkaConsumer多线程以及单KafkaConsumer多线程.在第二种 ...

  8. JAVA之旅(十二)——Thread,run和start的特点,线程运行状态,获取线程对象和名称,多线程实例演示,使用Runnable接口

    JAVA之旅(十二)--Thread,run和start的特点,线程运行状态,获取线程对象和名称,多线程实例演示,使用Runnable接口 开始挑战一些难度了,线程和I/O方面的操作了,继续坚持 一. ...

  9. Qt5.9一个简单的多线程实例(类QThread)(第一种方法)

    Qt开启多线程,主要用到类QThread.有两种方法,第一种用一个类继承QThread,然后重新改写虚函数run().当要开启新线程时,只需要实例该类,然后调用函数start(),就可以开启一条多线程 ...

随机推荐

  1. VxWorks 6.9 内核编程指导之读书笔记 -- VxWorks kernel application (一)

    #1 什么是内核应用程序? #2 开发内核应用程序注意事项 什么是内核应用程序? 内核应用程序不同于RTP程序,它允许在内核态,与操作系统使用相同的地址空间.因此,它与操作系统会相互干扰.它可以编译成 ...

  2. 9款超绚丽的HTML5/CSS3应用和动画特效

    1.CSS3飘带状3D菜单 菜单带小图标 这次我们要来分享一款很特别的CSS3菜单,菜单的外观是飘带状的,并且每一个菜单项有一个精美的小图标,鼠标滑过菜单项时,菜单项就会向上凸起,像是飘带飘动一样,形 ...

  3. conditon监视器接口

    conditon监视器接口的实例对象必须通过Lock.newCondition()建立 立

  4. 进程通信---FIFO

    管道没有名字,所以只能在具有血缘关系的进程间使用,而在无名管道发展出来的有名管道FIFO,则有路径名与之相关联,以一种特殊设备文件形式存在于文件系统中,从而允许无亲缘关系的进程访问FIFO,下面看FI ...

  5. Low-poly低面建模(低像素多边形)

    概念 继拟物化.扁平化(Flat Design).长阴影(Long Shadow)之后,低多边形(Low Poly)又火速掀起了最新设计风潮.这种设计风格在早期计算机建模和动效中就被广泛采用,在快要被 ...

  6. Tabbar视图切换,返回上一视图,添加item

    前面有一篇博文iOS学习之Tab Bar的使用和视图切换 这是在AppDelegate里使用Tabbar,这样的程序打开就是TabbarView了,有时候我们需要给程序做一些帮助页面,或者登录页面,之 ...

  7. Log4Net总结

    Log4Net是用来记录日志的,可以将程序运行过程中的信息输出到一些地方(文件.数据库.EventLog等),日志就是程序的黑匣子,可以通过日志查看系统的运行过程,从而发现系统的问题.日志的作用:将运 ...

  8. Ubuntu 在未知root密码的情况下修改root密码

    一, 开机按 F12 (或长按Shift), 进入GRUB界面. 二, 在 recovery mode 按e Ubuntu, Linux 3.5.0-17-generic (恢复模式) (或recov ...

  9. jquery实现ajax,返回json数据

    jquery实现ajax可以调用几种方法 我经常用的是$get(url,data,callback,type)方法 其中url是异步请求的页面(可以是.ashx文件),data是参数,callback ...

  10. SQL左连接、右连接和内连接的简单示例

    left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录: right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录: inner join(等值连接 ...