简介

  使用线程的主要原因:应用程序中一些操作需要消耗一定的时间,比如对文件、数据库、网络的访问等等,而我们不希望用户一直等待到操作结束,而是在此同时可以进行一些其他的操作。 
  这就可以使用线程来实现。 
  本文主要介绍关于Thread和ThreadPool的基础知识。

Thread类

  基本用法

  使用Thread类可以创建和控制线程,在下面的示例代码中,Thread类的构造函数重载为接受ThreadStart和ParameterizedThreadStart类型的委托参数。ThreadStart委托定义了一个返回类型为void的无参数方法,在创建Thread对象后,就可以用Start()方法启动线程。

  1. using System;
  2. using System.Threading;
  3.  
  4. namespace ThreadDemo
  5. {
  6. class Program
  7. {
  8. static void Main()
  9. {
  10. var t1 = new Thread(ThreadMain);
  11. t1.Start();
  12. Console.WriteLine("This is the main thread.");
  13. }
  14. static void ThreadMain()
  15. {
  16. Console.WriteLine("Running in a thread.");
  17. }
  18. }
  19. }

  程序执行结果,得到两个线程的输出: 
  This is the main thread. 
  Running in a thread. 
  我们知道,我们并不能保证那个结果先输出,这由操作系统调度决定。

  在前文中,我们探讨了将Lambda表达式和异步委托结合使用,这里我们也使用Lambda表达式与来给Thread类构造函数传递参数: 
  

  1. using System.Threading;
  2.  
  3. namespace ThreadDemo
  4. {
  5. class Program
  6. {
  7. static void Main()
  8. {
  9. var t1 = new Thread(()=>Console.WriteLine("Running in a thread, id : {0}",Thread.CurrentThread.ManagedThreadId));
  10. t1.Start();
  11. Console.WriteLine("This is the main thread, id : {0}",Thread.CurrentThread.ManagedThreadId);
  12. }
  13. }
  14. }

  在应用程序的输出中,我们可以看到线程id,当然,每次运行的结果不一定一样,因为系统每次分配的线程是独立的。 
  This is the main thread, id : 1. 
  Running in a thread, id : 3.

  给线程传递数据

  前面的例子中,我们开启的新线程只是执行了一个简单的输出指令,并没有线程中的方法赋予参数。现在我们来探讨如何给线程传递参数,也就是传递数据。 
  一种方式是使用带ParameterizedThreadStart委托参数的Thread构造函数; 
  另一种方法是将自定义的方法传递给线程,然后启动线程。 
   
  ● 方法一:使用ParameterizedThreadStart委托。 
  该委托的实例方法必须带有一个object参数,而且返回类型为void。 
  假设该委托实例方法如下:

  1. static void ThreadMainWithParameters(object o)
  2. {
  3. ...
  4. ...
  5. }

  那么我可以这样开启线程:

  1. var o = new object();
  2. var t1 = new Thread(ThreadMainWithParameters);
  3. t1.Start(o);

  ● 方法二:使用自定义方法。 
  假设我们有一个MyThread类,该类有一个方法ThreaMain():

  1. public class MyThread
  2. {
  3. ...
  4. ...
  5. public void ThreadMain()
  6. {
  7. ...
  8. ...
  9. }
  10. ...
  11. ...
  12. }

  开启线程方法如下: 

  1. var o = new MyThread();
  2. var t1 =new Thread(o.ThreadMain);
  3. t1.Start();

线程池

  我们知道,线程的创建需要时间。 如果有不同的小任务要完成,我们就可以事先创建许多线程, 在应完成这些任务时发出请求。 这个线程数最好在需要更多的线程时增加,在需要释放资源时减少。 
  这些线程就是放在线程池中,C#为我们提供了一个管理线程池的类:ThreadPool。 
  它会在需要的时候增减线程池中的线程数,如果线程池中线程数到达上限,新的作业就需要排队等待其他线程完成其任务。 
   
  下面的示例应用程序首先要读取工作线程和 I/O线程的最大线程数,把这些信息写入控制台中。接着在for循环中,调用 ThreadPool.QueueUserWorkItem()方法,传递一个WaitCallBack类型的委托,把 JobForThread()方法赋予线程池中的线程。线程池收到这个请求后,就会从池中选择一个线程,来调用该方法。 如果线程池还没有运行,就会创建一个线程池,并启动第一个线程。 如果线程池己经在运行,且有一个空闲线程来完成该任务,就把该作业传递给这个线程。 
  

  1. using System;
  2. using System.Threading;
  3.  
  4. namespace ThreadDemo
  5. {
  6. class program
  7. {
  8. static void Main()
  9. {
  10. int nWorkThreads;
  11. int nCompletionPortThreads;
  12. ThreadPool.GetMaxThreads(out nWorkThreads, out nCompletionPortThreads);
  13. Console.WriteLine("Max worker threads: {0}, I/O completion threads: {1}",nWorkThreads, nCompletionProtThreads);
  14. for(int i = ; i < ; i++)
  15. {
  16. ThreadPool.QueueUserWorkItem(JobForAThread);
  17. }
  18. Thread.Sleep();
  19. }
  20.  
  21. static void JobForAThread(object state)
  22. {
  23. for(int i = ; i < ; i++)
  24. {
  25. Console.WriteLine("loop {0}, running inside pooled thread {1}", i, Thread.CurrentThread.ManagedThreadId);
  26. Thread.Sleep();
  27. }
  28. }
  29. }
  30. }

  读者运行该程序的结果可能与此不同,也可以改变作业的睡眠时间和要处理的作业数,得到完全不同的结果。 
  

  线程池使用起来很简单,但它有一些限制 : 
  ● 线程池中的所有线程都是后台线程 。 如果进程的所有前台线程都结束了,所有的后台线程就会停止。 不能把入池的线程改为前台线程 。 
  ● 不能给入池的线程设置优先级或名称。 
  ● 对于 COM对 象,入池的所有线程都是多线程单元(multit-threaded apartment , MTA)线程。 许 COM对象都需要单线程单元(single-threaded apartment , STA)线 程。 
  ● 入池的线程只能用于时间较短的任务。 如果线程要一直运行(如Word的拼写检查器线程),就应使用Thread类创建一个线程。

转载来源 http://blog.csdn.net/honantic/article/details/46472647

LINQ查询表达式详解(1)——基本语法、使用扩展方法和Lambda表达式简化LINQ查询的更多相关文章

  1. C#中的委托,匿名方法和Lambda表达式

    简介 在.NET中,委托,匿名方法和Lambda表达式很容易发生混淆.我想下面的代码能证实这点.下面哪一个First会被编译?哪一个会返回我们需要的结果?即Customer.ID=.答案是6个Firs ...

  2. 写的非常好的文章 C#中的委托,匿名方法和Lambda表达式

    简介 在.NET中,委托,匿名方法和Lambda表达式很容易发生混淆.我想下面的代码能证实这点.下面哪一个First会被编译?哪一个会返回我们需要的结果?即Customer.ID=5.答案是6个Fir ...

  3. (转)C#中的委托,匿名方法和Lambda表达式

    简介 在.NET中,委托,匿名方法和Lambda表达式很容易发生混淆.我想下面的代码能证实这点.下面哪一个First会被编译?哪一个会返回我们需要的结果?即Customer.ID=5.答案是6个Fir ...

  4. [No0000134]C#中的委托,匿名方法和Lambda表达式

    简介 在.NET中,委托,匿名方法和Lambda表达式很容易发生混淆.我想下面的代码能证实这点.下面哪一个First会被编译?哪一个会返回我们需要的结果?即Customer.ID=5.答案是6个Fir ...

  5. 【转】C#中的委托,匿名方法和Lambda表达式

    简介 在.NET中,委托,匿名方法和Lambda表达式很容易发生混淆.我想下面的代码能证实这点.下面哪一个First会被编译?哪一个会返回我们需要的结果?即Customer.ID=5.答案是6个Fir ...

  6. 委托学习总结(二)匿名方法和lambda表达式

    之前总结了委托这个困惑着大多初学者的概念,继续来学习匿名方法和lambda表达式 (1)我们之前写了这样一段代码 //自定义一个委托 public delegate int Expression(in ...

  7. 匿名方法和Lambda表达式

    匿名方法本质上是一传递给委托的代码块,是使用委托的另一种方法. 规则: 1.匿名方法中不能使用跳转语句跳至次匿名方法的外部,反之亦然:匿名方法外部的跳转语句也不能跳转到匿名方法的内部: 2.在匿名方法 ...

  8. 匿名方法和Lambda 表达式

    Overview 当你使用委托的时候,有时候是否会感觉到略微有些麻烦,尽管委托已经极大的减少了我们的工作量,比如,有一个方法,只需要使用一次,仅仅是传递给委托,我们就要定义一次他,这未免太 " ...

  9. c#委托中的匿名方法和lambda表达式

    一.一般委托方式 Func<int, int, int> AddMethodHander; public unName() { AddMethodHander += AddMethod; ...

随机推荐

  1. 部署flask到阿里云服务器ECS

    比较难的一点是:部署到云服务器上之后,通过公网没法访问. 这就要说回道 本地开发时的一个小细节:通过http://127.0.0.1:5000是可以访问的,但通过http://[本地ip]:5000是 ...

  2. HDU 6053 - TrickGCD | 2017 Multi-University Training Contest 2

    /* HDU 6053 - TrickGCD [ 莫比乌斯函数,筛法分块 ] | 2017 Multi-University Training Contest 2 题意: 给出数列 A[N],问满足: ...

  3. vue实例之组件开发:图片轮播组件

    一.普通方式: 其中,index是关键. <!DOCTYPE html> <html lang="en"> <head> <meta ch ...

  4. CodeForces 724C Ray Tracing(碰撞类,扩展gcd)

    又一次遇到了碰撞类的题目,还是扩展gcd和同余模方程.上次博客的链接在这:http://www.cnblogs.com/zzyDS/p/5874440.html. 现在干脆解同余模直接按照套路来吧,如 ...

  5. C++入门经典-例7.6-this指针,同一个类的不同对象数据

    1:对于类的非静态成员,每个对象都有自己的一份拷贝,即每个对象都有自己的数据成员,不过成员函数却是每个对象共享的.那么调用共享的成员函数如何找到自己的数据成员呢?答案是通过类中隐藏的this指针. 2 ...

  6. 卷boot仅剩余XX空间

    参见: https://blog.csdn.net/hnzcdy/article/details/52381844

  7. pycharm创建.py文件时,自动添加头文件注释

    File->settings->Editor->Code Templates->Python Script 添加以下代码: #!/usr/bin/env python # -* ...

  8. 【好书推荐】9、安卓Andorid编程吐血整理100+本

    点开即可

  9. 苹果应用(.ipa)打包和上传,不用通过苹果商店即可用

    签名工具: appuploader(.p12:.cer) 打包平台: http://www.lbuilder.com(收费) 上传平台: http://www.58apk.com (每日50次下载,加 ...

  10. java8 lamda 表达式