LINQ查询表达式详解(1)——基本语法、使用扩展方法和Lambda表达式简化LINQ查询
简介
使用线程的主要原因:应用程序中一些操作需要消耗一定的时间,比如对文件、数据库、网络的访问等等,而我们不希望用户一直等待到操作结束,而是在此同时可以进行一些其他的操作。
这就可以使用线程来实现。
本文主要介绍关于Thread和ThreadPool的基础知识。
Thread类
基本用法
使用Thread类可以创建和控制线程,在下面的示例代码中,Thread类的构造函数重载为接受ThreadStart和ParameterizedThreadStart类型的委托参数。ThreadStart委托定义了一个返回类型为void的无参数方法,在创建Thread对象后,就可以用Start()方法启动线程。
- using System;
- using System.Threading;
- namespace ThreadDemo
- {
- class Program
- {
- static void Main()
- {
- var t1 = new Thread(ThreadMain);
- t1.Start();
- Console.WriteLine("This is the main thread.");
- }
- static void ThreadMain()
- {
- Console.WriteLine("Running in a thread.");
- }
- }
- }
程序执行结果,得到两个线程的输出:
This is the main thread.
Running in a thread.
我们知道,我们并不能保证那个结果先输出,这由操作系统调度决定。
在前文中,我们探讨了将Lambda表达式和异步委托结合使用,这里我们也使用Lambda表达式与来给Thread类构造函数传递参数:
- using System.Threading;
- namespace ThreadDemo
- {
- class Program
- {
- static void Main()
- {
- var t1 = new Thread(()=>Console.WriteLine("Running in a thread, id : {0}",Thread.CurrentThread.ManagedThreadId));
- t1.Start();
- Console.WriteLine("This is the main thread, id : {0}",Thread.CurrentThread.ManagedThreadId);
- }
- }
- }
在应用程序的输出中,我们可以看到线程id,当然,每次运行的结果不一定一样,因为系统每次分配的线程是独立的。
This is the main thread, id : 1.
Running in a thread, id : 3.
给线程传递数据
前面的例子中,我们开启的新线程只是执行了一个简单的输出指令,并没有线程中的方法赋予参数。现在我们来探讨如何给线程传递参数,也就是传递数据。
一种方式是使用带ParameterizedThreadStart委托参数的Thread构造函数;
另一种方法是将自定义的方法传递给线程,然后启动线程。
● 方法一:使用ParameterizedThreadStart委托。
该委托的实例方法必须带有一个object参数,而且返回类型为void。
假设该委托实例方法如下:
- static void ThreadMainWithParameters(object o)
- {
- ...
- ...
- }
那么我可以这样开启线程:
- var o = new object();
- var t1 = new Thread(ThreadMainWithParameters);
- t1.Start(o);
● 方法二:使用自定义方法。
假设我们有一个MyThread类,该类有一个方法ThreaMain():
- public class MyThread
- {
- ...
- ...
- public void ThreadMain()
- {
- ...
- ...
- }
- ...
- ...
- }
开启线程方法如下:
- var o = new MyThread();
- var t1 =new Thread(o.ThreadMain);
- t1.Start();
线程池
我们知道,线程的创建需要时间。 如果有不同的小任务要完成,我们就可以事先创建许多线程, 在应完成这些任务时发出请求。 这个线程数最好在需要更多的线程时增加,在需要释放资源时减少。
这些线程就是放在线程池中,C#为我们提供了一个管理线程池的类:ThreadPool。
它会在需要的时候增减线程池中的线程数,如果线程池中线程数到达上限,新的作业就需要排队等待其他线程完成其任务。
下面的示例应用程序首先要读取工作线程和 I/O线程的最大线程数,把这些信息写入控制台中。接着在for循环中,调用 ThreadPool.QueueUserWorkItem()方法,传递一个WaitCallBack类型的委托,把 JobForThread()方法赋予线程池中的线程。线程池收到这个请求后,就会从池中选择一个线程,来调用该方法。 如果线程池还没有运行,就会创建一个线程池,并启动第一个线程。 如果线程池己经在运行,且有一个空闲线程来完成该任务,就把该作业传递给这个线程。
- using System;
- using System.Threading;
- namespace ThreadDemo
- {
- class program
- {
- static void Main()
- {
- int nWorkThreads;
- int nCompletionPortThreads;
- ThreadPool.GetMaxThreads(out nWorkThreads, out nCompletionPortThreads);
- Console.WriteLine("Max worker threads: {0}, I/O completion threads: {1}",nWorkThreads, nCompletionProtThreads);
- for(int i = ; i < ; i++)
- {
- ThreadPool.QueueUserWorkItem(JobForAThread);
- }
- Thread.Sleep();
- }
- static void JobForAThread(object state)
- {
- for(int i = ; i < ; i++)
- {
- Console.WriteLine("loop {0}, running inside pooled thread {1}", i, Thread.CurrentThread.ManagedThreadId);
- Thread.Sleep();
- }
- }
- }
- }
读者运行该程序的结果可能与此不同,也可以改变作业的睡眠时间和要处理的作业数,得到完全不同的结果。
线程池使用起来很简单,但它有一些限制 :
● 线程池中的所有线程都是后台线程 。 如果进程的所有前台线程都结束了,所有的后台线程就会停止。 不能把入池的线程改为前台线程 。
● 不能给入池的线程设置优先级或名称。
● 对于 COM对 象,入池的所有线程都是多线程单元(multit-threaded apartment , MTA)线程。 许 COM对象都需要单线程单元(single-threaded apartment , STA)线 程。
● 入池的线程只能用于时间较短的任务。 如果线程要一直运行(如Word的拼写检查器线程),就应使用Thread类创建一个线程。
转载来源 http://blog.csdn.net/honantic/article/details/46472647
LINQ查询表达式详解(1)——基本语法、使用扩展方法和Lambda表达式简化LINQ查询的更多相关文章
- C#中的委托,匿名方法和Lambda表达式
简介 在.NET中,委托,匿名方法和Lambda表达式很容易发生混淆.我想下面的代码能证实这点.下面哪一个First会被编译?哪一个会返回我们需要的结果?即Customer.ID=.答案是6个Firs ...
- 写的非常好的文章 C#中的委托,匿名方法和Lambda表达式
简介 在.NET中,委托,匿名方法和Lambda表达式很容易发生混淆.我想下面的代码能证实这点.下面哪一个First会被编译?哪一个会返回我们需要的结果?即Customer.ID=5.答案是6个Fir ...
- (转)C#中的委托,匿名方法和Lambda表达式
简介 在.NET中,委托,匿名方法和Lambda表达式很容易发生混淆.我想下面的代码能证实这点.下面哪一个First会被编译?哪一个会返回我们需要的结果?即Customer.ID=5.答案是6个Fir ...
- [No0000134]C#中的委托,匿名方法和Lambda表达式
简介 在.NET中,委托,匿名方法和Lambda表达式很容易发生混淆.我想下面的代码能证实这点.下面哪一个First会被编译?哪一个会返回我们需要的结果?即Customer.ID=5.答案是6个Fir ...
- 【转】C#中的委托,匿名方法和Lambda表达式
简介 在.NET中,委托,匿名方法和Lambda表达式很容易发生混淆.我想下面的代码能证实这点.下面哪一个First会被编译?哪一个会返回我们需要的结果?即Customer.ID=5.答案是6个Fir ...
- 委托学习总结(二)匿名方法和lambda表达式
之前总结了委托这个困惑着大多初学者的概念,继续来学习匿名方法和lambda表达式 (1)我们之前写了这样一段代码 //自定义一个委托 public delegate int Expression(in ...
- 匿名方法和Lambda表达式
匿名方法本质上是一传递给委托的代码块,是使用委托的另一种方法. 规则: 1.匿名方法中不能使用跳转语句跳至次匿名方法的外部,反之亦然:匿名方法外部的跳转语句也不能跳转到匿名方法的内部: 2.在匿名方法 ...
- 匿名方法和Lambda 表达式
Overview 当你使用委托的时候,有时候是否会感觉到略微有些麻烦,尽管委托已经极大的减少了我们的工作量,比如,有一个方法,只需要使用一次,仅仅是传递给委托,我们就要定义一次他,这未免太 " ...
- c#委托中的匿名方法和lambda表达式
一.一般委托方式 Func<int, int, int> AddMethodHander; public unName() { AddMethodHander += AddMethod; ...
随机推荐
- 部署flask到阿里云服务器ECS
比较难的一点是:部署到云服务器上之后,通过公网没法访问. 这就要说回道 本地开发时的一个小细节:通过http://127.0.0.1:5000是可以访问的,但通过http://[本地ip]:5000是 ...
- HDU 6053 - TrickGCD | 2017 Multi-University Training Contest 2
/* HDU 6053 - TrickGCD [ 莫比乌斯函数,筛法分块 ] | 2017 Multi-University Training Contest 2 题意: 给出数列 A[N],问满足: ...
- vue实例之组件开发:图片轮播组件
一.普通方式: 其中,index是关键. <!DOCTYPE html> <html lang="en"> <head> <meta ch ...
- CodeForces 724C Ray Tracing(碰撞类,扩展gcd)
又一次遇到了碰撞类的题目,还是扩展gcd和同余模方程.上次博客的链接在这:http://www.cnblogs.com/zzyDS/p/5874440.html. 现在干脆解同余模直接按照套路来吧,如 ...
- C++入门经典-例7.6-this指针,同一个类的不同对象数据
1:对于类的非静态成员,每个对象都有自己的一份拷贝,即每个对象都有自己的数据成员,不过成员函数却是每个对象共享的.那么调用共享的成员函数如何找到自己的数据成员呢?答案是通过类中隐藏的this指针. 2 ...
- 卷boot仅剩余XX空间
参见: https://blog.csdn.net/hnzcdy/article/details/52381844
- pycharm创建.py文件时,自动添加头文件注释
File->settings->Editor->Code Templates->Python Script 添加以下代码: #!/usr/bin/env python # -* ...
- 【好书推荐】9、安卓Andorid编程吐血整理100+本
点开即可
- 苹果应用(.ipa)打包和上传,不用通过苹果商店即可用
签名工具: appuploader(.p12:.cer) 打包平台: http://www.lbuilder.com(收费) 上传平台: http://www.58apk.com (每日50次下载,加 ...
- java8 lamda 表达式