3.1 使用ThreadStart委托

这里先以一个例子体现一下多线程带来的好处,首先在Message类中建立一个方法ShowMessage(),里面显示了当前运行线程的Id,并使用Thread.Sleep(int ) 方法模拟部分工作。在main()中通过ThreadStart委托绑定Message对象的ShowMessage()方法,然后通过Thread.Start()执行异步方法。

 1       public class Message 2       { 3           public void ShowMessage() 4           { 5               string message = string.Format("Async threadId is :{0}", 6                                               Thread.CurrentThread.ManagedThreadId); 7               Console.WriteLine(message); 8    9               for (int n = 0; n < 10; n++)10               {11                   Thread.Sleep(300);   12                   Console.WriteLine("The number is:" + n.ToString()); 13               }14           }15       }16   17       class Program18       {19           static void Main(string[] args)20           {21               Console.WriteLine("Main threadId is:"+22                                 Thread.CurrentThread.ManagedThreadId);23               Message message=new Message();24               Thread thread = new Thread(new ThreadStart(message.ShowMessage));25               thread.Start();26               Console.WriteLine("Do something ..........!");27               Console.WriteLine("Main thread working is complete!");28               29           }30       }

请注意运行结果,在调用Thread.Start()方法后,系统以异步方式运行Message.ShowMessage(),而主线程的操作是继续执行的,在Message.ShowMessage()完成前,主线程已完成所有的操作。

3.2 使用ParameterizedThreadStart委托

ParameterizedThreadStart委托与ThreadStart委托非常相似,但ParameterizedThreadStart委托是面向带参数方法的。注意ParameterizedThreadStart 对应方法的参数为object,此参数可以为一个值对象,也可以为一个自定义对象。

 1     public class Person 2     { 3         public string Name 4         { 5             get; 6             set; 7         } 8         public int Age 9         {10             get;11             set;12         }13     }14 15     public class Message16     {17         public void ShowMessage(object person)18         {19             if (person != null)20             {21                 Person _person = (Person)person;22                 string message = string.Format("\n{0}'s age is {1}!\nAsync threadId is:{2}",23                     _person.Name,_person.Age,Thread.CurrentThread.ManagedThreadId);24                 Console.WriteLine(message);25             }26             for (int n = 0; n < 10; n++)27             {28                 Thread.Sleep(300);   29                 Console.WriteLine("The number is:" + n.ToString()); 30             }31         }32     }33 34     class Program35     {36         static void Main(string[] args)37         {     38             Console.WriteLine("Main threadId is:"+Thread.CurrentThread.ManagedThreadId);39             40             Message message=new Message();41             //绑定带参数的异步方法42             Thread thread = new Thread(new ParameterizedThreadStart(message.ShowMessage));43             Person person = new Person();44             person.Name = "Jack";45             person.Age = 21;46             thread.Start(person);  //启动异步线程 47             48             Console.WriteLine("Do something ..........!");49             Console.WriteLine("Main thread working is complete!");50              51         }52     }

运行结果:

3.3 前台线程与后台线程

注意以上两个例子都没有使用Console.ReadKey(),但系统依然会等待异步线程完成后才会结束。这是因为使用Thread.Start()启动的线程默认为前台线程,而系统必须等待所有前台线程运行结束后,应用程序域才会自动卸载。

在第二节曾经介绍过线程Thread有一个属性IsBackground,通过把此属性设置为true,就可以把线程设置为后台线程!这时应用程序域将在主线程完成时就被卸载,而不会等待异步线程的运行。

3.4 挂起线程

为了等待其他后台线程完成后再结束主线程,就可以使用Thread.Sleep()方法。

 1     public class Message 2     { 3         public void ShowMessage() 4         { 5             string message = string.Format("\nAsync threadId is:{0}", 6                                            Thread.CurrentThread.ManagedThreadId); 7             Console.WriteLine(message); 8             for (int n = 0; n < 10; n++) 9             {10                 Thread.Sleep(300);11                 Console.WriteLine("The number is:" + n.ToString());12             }13         }14     }15 16     class Program17     {18         static void Main(string[] args)19         {     20             Console.WriteLine("Main threadId is:"+21                               Thread.CurrentThread.ManagedThreadId);22             23             Message message=new Message();24             Thread thread = new Thread(new ThreadStart(message.ShowMessage));25             thread.IsBackground = true;26             thread.Start();27             28             Console.WriteLine("Do something ..........!");29             Console.WriteLine("Main thread working is complete!");30             Console.WriteLine("Main thread sleep!");31             Thread.Sleep(5000);32         }33     }

运行结果如下,此时应用程序域将在主线程运行5秒后自动结束

但系统无法预知异步线程需要运行的时间,所以用通过Thread.Sleep(int)阻塞主线程并不是一个好的解决方法。有见及此,.NET专门为等待异步线程完成开发了另一个方法thread.Join()。把上面例子中的最后一行Thread.Sleep(5000)修改为 thread.Join() 就能保证主线程在异步线程thread运行结束后才会终止。

3.5 Suspend 与 Resume (慎用)

Thread.Suspend()与 Thread.Resume()是在Framework1.0 就已经存在的老方法了,它们分别可以挂起、恢复线程。但在Framework2.0中就已经明确排斥这两个方法。这是因为一旦某个线程占用了已有的资源,再使用Suspend()使线程长期处于挂起状态,当在其他线程调用这些资源的时候就会引起死锁!所以在没有必要的情况下应该避免使用这两个方法。

3.6 终止线程

若想终止正在运行的线程,可以使用Abort()方法。在使用Abort()的时候,将引发一个特殊异常 ThreadAbortException 。
若想在线程终止前恢复线程的执行,可以在捕获异常后 ,在catch(ThreadAbortException ex){...} 中调用Thread.ResetAbort()取消终止。
而使用Thread.Join()可以保证应用程序域等待异步线程结束后才终止运行。

 1          static void Main(string[] args) 2          { 3              Console.WriteLine("Main threadId is:" + 4                                Thread.CurrentThread.ManagedThreadId); 5   6              Thread thread = new Thread(new ThreadStart(AsyncThread)); 7              thread.IsBackground = true; 8              thread.Start(); 9              thread.Join();10  11          }     12          13          //以异步方式调用14          static void AsyncThread()15          {16              try17              {18                  string message = string.Format("\nAsync threadId is:{0}",19                     Thread.CurrentThread.ManagedThreadId);20                  Console.WriteLine(message);21  22                  for (int n = 0; n < 10; n++)23                  {24                      //当n等于4时,终止线程25                      if (n >= 4)26                      {27                          Thread.CurrentThread.Abort(n);28                      }29                      Thread.Sleep(300);30                      Console.WriteLine("The number is:" + n.ToString());31                  }32              }33              catch (ThreadAbortException ex)34              {35                  //输出终止线程时n的值36                  if (ex.ExceptionState != null)37                      Console.WriteLine(string.Format("Thread abort when the number is: {0}!", 38                                                       ex.ExceptionState.ToString()));39                 40                  //取消终止,继续执行线程41                  Thread.ResetAbort();42                  Console.WriteLine("Thread ResetAbort!");43              }44  45              //线程结束46              Console.WriteLine("Thread Close!");47          }

运行结果如下

转载于:https://www.cnblogs.com/meilibao/archive/2012/10/16/2725736.html

以ThreadStart方式实现多线程相关推荐

  1. java的多线程实现方式_java 多线程实现方式

    本文主要是对java 多线程知识的总结,做个记录,温故知新. 多线程有三种实现方式,具体如下. 继承Thread类创建线程类 重写run方法,完成线程需要做的任务. 创建实例 调用start()启动线 ...

  2. 操作系统(十二)线程的实现方式、多线程模型

    2.1.6 线程的实现方式.多线程模型 目录 2.1.6 线程的实现方式.多线程模型 2.1.6.1 线程的实现方式 2.1.6.2 多线程模型 2.1.6.1 线程的实现方式   线程已在许多系统中 ...

  3. java 多线程两种方式_JAVA多线程实现的两种方式

    java多线程实现方式主要有两种:继承Thread类.实现Runnable接口 1.继承Thread类实现多线程 继承Thread类的方法尽管被我列为一种多线程实现方式,但Thread本质上也是实现了 ...

  4. 线程实现的方式、多线程模型

    文章目录 前言 一.用户级线程 二.内核级线程 三.组合实现 四.多线程模型 1.多对一模型 2.一对一模型 3.多对多模型 前言 参考文章:https://blog.csdn.net/qq_4060 ...

  5. java多线程的实现方式_JAVA多线程实现的三种方式

    最近在做代码优化时学习和研究了下JAVA多线程的使用,看了菜鸟们的见解后做了下总结. 1.JAVA多线程实现方式 JAVA多线程实现方式主要有三种:继承Thread类.实现Runnable接口.使用E ...

  6. Lambda方式创建多线程

    Lambda方式创建多线程 一.Lambda表达式的标准格式 Lamdba创建线程,是对匿名内部类创建多线程的简化 由三部分组成: a.一些参数b.一个箭头c.一段代码 格式: (参数列表)-> ...

  7. 多线程初探:三种方式创建多线程详细示例

    多线程即在同一时间,可以做多件事情. 创建多线程有3种方式,分别是继承线程类,实现Runnable接口,匿名类 一:线程概念 首先要理解进程(Processor)和线程(Thread)的区别 进程:启 ...

  8. java多线程的实现方式_Java 多线程(一)——多线程的实现方式

    一.前言 Java 异常的处理方式与自定义异常 我们已经讲完了,从今天开始我们来学习多线程. 二.与多线程相关的概念 2.1.并发与并行并发:指两个或多个事件在同一个时间段内发生,具体如下图所示: 并 ...

  9. java实现线程的方式_java多线程实现的四种方式

    java多线程实现的四种方式1.继承Thread类,重写run方法(其实Thread类本身也实现了Runnable接口) 2.实现Runnable接口,重写run方法 3.实现Callable接口,重 ...

最新文章

  1. 组会PPT202006220717《双研究步骤的螺旋波等离子体放电结果分析》
  2. 直播 | WWW 2021:用先验知识指导BERT注意力机制的语义文本匹配
  3. bash: gitbook: command not found
  4. 聊聊JVM(六)理解JVM的safepoint
  5. python数据库模糊查询_Python操作mongodb数据库进行模糊查询操作示例
  6. count(1),count(*),count(主键) 性能对比及辟谣
  7. lombok之@Slf4j注解
  8. Shiro学习总结(3)——Apache Shiro身份认证
  9. java编译可执行文件_Java编译器完成但没有创建可执行文件?
  10. jdbctemplate mysql 配置_Spring Boot 初级入门教程(十四) —— 配置 MySQL 数据库和使用 JdbcTemplate 测试...
  11. 零基础学python用哪本书好-零基础学习python推荐几本书?
  12. EditText以及登录UI实现
  13. echarts改变颜色属性的demo
  14. 【GD32L233C-START】11、GD32 ISP软件还不支持GD32L233
  15. JDBC下载,使用,访问数据库
  16. php image函数,操作压缩图片时,png图片压缩后整个图片变黑
  17. 数据库连接池种类、C3P0数据库连接池、德鲁伊数据库连接池
  18. 方法的重写和重载,接口和抽象类区别
  19. Visualization of Detail Point Set by Local Algebraic Sphere Fitting
  20. JASS代码翻译更新(第十篇)

热门文章

  1. 营销大数据分析 关键技术_营销分析的3个最关键技能
  2. 配对交易方法_COVID下的自适应配对交易,一种强化学习方法
  3. linux kernel 三次握手建立TCP链接的实现
  4. Jacobi并行拆解【补充】
  5. 企业贷款还不上,股东有偿还责任吗?
  6. 信用卡如何安全取现?
  7. 为女儿示范的两张石膏像素描
  8. FIFO的verilog代码
  9. python控制鼠标_如何用python实现真实的鼠标移动?
  10. php array 如何访问,php – 如何访问$array [@key]值