创建线程

线程的基本操作

线程和其它常见的类一样,有着很多属性和方法,参考下表:

创建线程的方法有很多种,这里我们先从thread开始创建线程

  class Program
{
static void Main(string[] args)
{
Thread t = new Thread(PrintNumbers);
t.Start();
PrintNumbers();
} static void PrintNumbers()
{
Console.WriteLine("Starting...");
for (int i = 0; i < 10; i++)
{
Console.WriteLine(i);
}
}
}

Thread构造函数接受两种委托

    public delegate void ThreadStart(); 无返回值、无参的

    public delegate void ParameterizedThreadStart(object obj);无返回值、参数为object类型的方法

既然构造函数是委托那么我还可以用lambda来简写

  Thread t = new Thread(()=> {
Console.WriteLine("Starting...");
for (int i = 0; i < 10; i++)
{
Console.WriteLine(i);
}
});
t.Start();

很多时候我们都需要线程执行的是一个有参的方法,下面看看如何调用有多个参数的方法,

        static void Main(string[] args)
{
int b = 10;
string c = "主线程";
Thread t = new Thread(()=> PrintNumbers(b,c)); t.Start(); }
static void PrintNumbers(int count,string name)
{
for (int i = 0; i < count; i++)
{
Console.WriteLine("name:{0},i:{1}",name,i);
}
}

Thread.Join()

我的理解是当调用Join()方法时主线程会停止工作,我不干活了,等你干完了我在继续干活如:

    static void Main(string[] args)
{
Thread.CurrentThread.Name = "主线程";
Console.WriteLine("线程名字:{0},线程工作状态:{1}", Thread.CurrentThread.Name, Thread.CurrentThread.ThreadState);
Thread abortThread = new Thread(AbortMethod);
abortThread.Name = "子线程";
abortThread.Start();
abortThread.Join(); Console.WriteLine("线程名字:{0},子线程工作状态:{1}", abortThread.Name, abortThread.ThreadState);
Console.WriteLine("继续干活"); Console.Read(); }
private static void AbortMethod()
{
Console.WriteLine("线程名字:{0},子线程工作状态:{1}",Thread.CurrentThread.Name,Thread.CurrentThread.ThreadState);
for (int i = 0; i < 5; i++)
{
Thread.Sleep(1000);
Console.WriteLine(i);
} }//输出结果线程名字:主线程,线程工作状态:Running
线程名字:子线程,子线程工作状态:Running
0
1
2
3
4
线程名字:子线程,子线程工作状态:Stopped
继续干活

Thread.Abort()

Abort()方法来终止线程的运行,我们在使用它的时候要主要,它是通过抛出ThreadAbortException异常的方式来终止线程的

      static void Main(string[] args)
{
Thread abortThread = new Thread(AbortMethod);
abortThread.Name = "test";
abortThread.Start();
Thread.Sleep(3000);
try
{
abortThread.Abort();
}
catch(Exception e)
{ Console.WriteLine("主线程:{0}", Thread.CurrentThread.Name);
} Console.WriteLine("我被开除了,子线程:{0},子线程状态:{1}", abortThread.Name, abortThread.ThreadState); Console.Read(); }
private static void AbortMethod()
{
try
{
Console.WriteLine("子线程:{0},子线程状态:{1}", Thread.CurrentThread.Name, Thread.CurrentThread.ThreadState);
Console.WriteLine("开始干活");
for (int i = 0; i < 5; i++)
{
Thread.Sleep(1000);
Console.WriteLine(i);
}
Console.WriteLine("继续干活");
}
catch (Exception e)
{
Console.WriteLine("类型:"+e.GetType().Name);
Console.WriteLine("子线程:{0},子线程状态:{1}", Thread.CurrentThread.Name, Thread.CurrentThread.ThreadState);
} }
输出
子线程:test,子线程状态:Running
开始干活
0
1
类型:ThreadAbortException
子线程:test,子线程状态:AbortRequested
我被开除了,子线程:test,子线程状态:Aborted

从运行结果可以看出,调用Abort方法的线程引发的异常类型为ThreadAbortException, 以及异常只会在 调用Abort方法的线程中发生,而不会在主线程中抛出,并且调用Abort方法后线程的状态不是立即改变为Aborted状态,而是从AbortRequested->Aborted。

Thread.ResetAbort()

Abort方法可以通过跑出ThreadAbortException异常中止线程,而使用ResetAbort方法可以取消中止线程的操作,下面通过代码演示使用 ResetAbort方法

      static void Main(string[] args)
{
Thread abortThread = new Thread(AbortMethod);
abortThread.Name = "test";
abortThread.Start();
Thread.Sleep(1000); try
{
abortThread.Abort(); }
catch(Exception e)
{ Console.WriteLine("主线程:{0}", Thread.CurrentThread.Name);
} Console.WriteLine("我被开除了,子线程:{0},子线程状态:{1}", abortThread.Name, abortThread.ThreadState); Console.Read(); }
private static void AbortMethod()
{
try
{
Console.WriteLine("我要被开除了"); for (int i = 0; i < 5; i++)
{ Thread.Sleep(1000);
Console.WriteLine(i); } }
catch (Exception e)
{
Thread.ResetAbort();
Console.WriteLine("类型:"+e.GetType().Name);
Console.WriteLine("子线程:{0},子线程状态:{1}", Thread.CurrentThread.Name, Thread.CurrentThread.ThreadState);
}
Console.WriteLine("我又回来继续干活");
} 输出
我要被开除了
我被开除了,子线程:test,子线程状态:AbortRequested
类型:ThreadAbortException
子线程:test,子线程状态:Running
我又回来继续干活

线程的优先级

如果在应用程序中有多个线程在运行,但一些线程比另一些线程重要,这种情况下可以在一个进程中为不同的线程指定不同的优先级。线程的优先级可以通过Thread类Priority属性设置,Priority属性是一个ThreadPriority型枚举,列举了5个优先等级:AboveNormal、BelowNormal、Highest、Lowest、Normal。公共语言运行库默认是Normal类型的。见下图:

c# 线程的基本使用的更多相关文章

  1. [ 高并发]Java高并发编程系列第二篇--线程同步

    高并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求, ...

  2. [高并发]Java高并发编程系列开山篇--线程实现

    Java是最早开始有并发的语言之一,再过去传统多任务的模式下,人们发现很难解决一些更为复杂的问题,这个时候我们就有了并发. 引用 多线程比多任务更加有挑战.多线程是在同一个程序内部并行执行,因此会对相 ...

  3. 多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类)

    前言:刚学习了一段机器学习,最近需要重构一个java项目,又赶过来看java.大多是线程代码,没办法,那时候总觉得多线程是个很难的部分很少用到,所以一直没下决定去啃,那些年留下的坑,总是得自己跳进去填 ...

  4. Java 线程

    线程:线程是进程的组成部分,一个进程可以拥有多个线程,而一个线程必须拥有一个父进程.线程可以拥有自己的堆栈,自己的程序计数器和自己的局部变量,但不能拥有系统资源.它与父进程的其他线程共享该进程的所有资 ...

  5. C++实现线程安全的单例模式

    在某些应用环境下面,一个类只允许有一个实例,这就是著名的单例模式.单例模式分为懒汉模式,跟饿汉模式两种. 首先给出饿汉模式的实现 template <class T> class sing ...

  6. 记一次tomcat线程创建异常调优:unable to create new native thread

    测试在进行一次性能测试的时候发现并发300个请求时出现了下面的异常: HTTP Status 500 - Handler processing failed; nested exception is ...

  7. Android线程管理之ThreadLocal理解及应用场景

    前言: 最近在学习总结Android的动画效果,当学到Android属性动画的时候大致看了下源代码,里面的AnimationHandler存取使用了ThreadLocal,激起了我很大的好奇心以及兴趣 ...

  8. C#多线程之线程池篇3

    在上一篇C#多线程之线程池篇2中,我们主要学习了线程池和并行度以及如何实现取消选项的相关知识.在这一篇中,我们主要学习如何使用等待句柄和超时.使用计时器和使用BackgroundWorker组件的相关 ...

  9. C#多线程之线程池篇2

    在上一篇C#多线程之线程池篇1中,我们主要学习了如何在线程池中调用委托以及如何在线程池中执行异步操作,在这篇中,我们将学习线程池和并行度.实现取消选项的相关知识. 三.线程池和并行度 在这一小节中,我 ...

  10. C#多线程之线程池篇1

    在C#多线程之线程池篇中,我们将学习多线程访问共享资源的一些通用的技术,我们将学习到以下知识点: 在线程池中调用委托 在线程池中执行异步操作 线程池和并行度 实现取消选项 使用等待句柄和超时 使用计时 ...

随机推荐

  1. javaweb消息中间件——rabbitmq入门

    概念:RabbitMQ是一款开源的消息中间件系统,由erlang开发,是AMQP的实现. 架构图大概如上. broker是消息队列的服务器,比如在linux上,我们安装的rabbitmq就是一个bro ...

  2. ES6系列_1之开发环境搭建

    前言: 1.es6的简单介绍: ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在2015年6月正式发布了.它的目标,是使得 JavaScript 语言 ...

  3. plsql 中文乱码

    plsql 中文乱码, 中文还是用ZHS16GBK insert into tt(id,name) values('2','张三'); select * from nls_database_param ...

  4. PHP环境 PDOException PDOException: could not find driver

    PDOException PDOException: could not find driver in dbcon.php:29 修改php.ini文件中的相关内容.对于找不到php.ini证明你的p ...

  5. 若(p,q)=1,则(p^n,q^n)=1

    [若(p,q)=1,则(p^n,q^n)=1] 因(p,q)=1,则p,q可分别表示成如下的形式: p=A^a*B^b*C^c, q=D^d*E^e*F^f 显示ABC.DEF无交集.而p^n.q^n ...

  6. Android中asset文件夹与raw文件夹的区别深入解析(转)

    *res/raw和assets的相同点:1.两者目录下的文件在打包后会原封不动的保存在apk包中,不会被编译成二进制.*res/raw和assets的不同点:1.res/raw中的文件会被映射到R.j ...

  7. SOCKET, TCP/UDP, HTTP, FTP 浅析

    SOCKET, TCP/UDP, HTTP, FTP (一)TCP/UDP,SOCKET,HTTP,FTP简析   TCP/IP是个协议组,可分为三个层次:网络层.传输层和应用层: 网络层:IP协议. ...

  8. Golang之函数练习

    小例题: package main import "fmt" /* 函数练习, 可变参数使用 写一个函数add 支持1个或多个int相加,并返回相加结果 写一个函数concat,支 ...

  9. css控制两个表格的边线重合

    控制两个表格的边线重合 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http:/ ...

  10. Java开发环境之------MyEclipse快捷键和排除错误第一选择ctrl+1(***重点***:ctrl+1,快速修复---有点像vs中的快速using

    using Java开发环境之------MyEclipse快捷键和排除错误第一选择ctrl+1(***重点***:ctrl+1,快速修复---有点像vs中的快速using 2015-06-29 浏览 ...