创建线程

线程的基本操作

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

创建线程的方法有很多种,这里我们先从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. hadoop学习day2开发笔记

    1.将hdfs客户端开发所需的jar导入工程(jar包可在hadoop安装包中找到common/hdfs) 2.写代码 要对hdfs中的文件进行操作,代码中首先需要获得一个hdfs的客户端对象 Con ...

  2. tensorflow-eagerAPI

    调用该API可以不通过 tensorflow.Session.run()调用 定义的张量constant tensor,可以直接print # -*- coding: utf-8 -*- from _ ...

  3. mysql统计一个库里面的表的总数

    SELECT COUNT(TABLE_NAME) FROM information_schema.tables WHERE TABLE_SCHEMA = 'weixin_platform' weixi ...

  4. Jenkins是什么?

    Jenkins 是一个可扩展的持续集成引擎. 主要用于: l 持续.自动地构建/测试软件项目. l 监控一些定时执行的任务. Jenkins拥有的特性包括: l 易于安装-只要把jenkins.war ...

  5. SourceTree安装和使用

    SourceTree 安装 需要注意的是在指定路径下添加一个json文件.就可以跳过身份验证,直接运行软件. SourceTree 的SSH配置 软件启动后,如果需要和远程的Gitlab仓库进行交互, ...

  6. mysql 删除死锁的事务

    select * from information_schema.innodb_trxkill 953

  7. #region 常量和静态变量静态类readonly

    #region 常量和静态变量静态类readonly //---------------------------------------------------------------------- ...

  8. Linux中shell变量$0,$?等含义

    linux中shell变量$#,$@,$0,$1,$2的基本含义: 变量说明: $$ Shell本身的PID(ProcessID) $! Shell最后运行的后台Process的PID $? 最后运行 ...

  9. JSP中系统Date的几点不符合中国时间观的地方

    正常调用系统时间的显示格式是Date date = new Date 显示出来的当前时间为Sun Nov 22 18:39:51 CST 2015 星期天的英文单词是Sun, 这个大家都是熟悉的, 这 ...

  10. Magic Potion(最大流,跑两遍网络流或者加一个中转点)

    Magic Potion http://codeforces.com/gym/101981/attachments/download/7891/20182019-acmicpc-asia-nanjin ...