c# 线程的基本使用
创建线程
线程的基本操作
线程和其它常见的类一样,有着很多属性和方法,参考下表:
创建线程的方法有很多种,这里我们先从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# 线程的基本使用的更多相关文章
- [ 高并发]Java高并发编程系列第二篇--线程同步
高并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求, ...
- [高并发]Java高并发编程系列开山篇--线程实现
Java是最早开始有并发的语言之一,再过去传统多任务的模式下,人们发现很难解决一些更为复杂的问题,这个时候我们就有了并发. 引用 多线程比多任务更加有挑战.多线程是在同一个程序内部并行执行,因此会对相 ...
- 多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类)
前言:刚学习了一段机器学习,最近需要重构一个java项目,又赶过来看java.大多是线程代码,没办法,那时候总觉得多线程是个很难的部分很少用到,所以一直没下决定去啃,那些年留下的坑,总是得自己跳进去填 ...
- Java 线程
线程:线程是进程的组成部分,一个进程可以拥有多个线程,而一个线程必须拥有一个父进程.线程可以拥有自己的堆栈,自己的程序计数器和自己的局部变量,但不能拥有系统资源.它与父进程的其他线程共享该进程的所有资 ...
- C++实现线程安全的单例模式
在某些应用环境下面,一个类只允许有一个实例,这就是著名的单例模式.单例模式分为懒汉模式,跟饿汉模式两种. 首先给出饿汉模式的实现 template <class T> class sing ...
- 记一次tomcat线程创建异常调优:unable to create new native thread
测试在进行一次性能测试的时候发现并发300个请求时出现了下面的异常: HTTP Status 500 - Handler processing failed; nested exception is ...
- Android线程管理之ThreadLocal理解及应用场景
前言: 最近在学习总结Android的动画效果,当学到Android属性动画的时候大致看了下源代码,里面的AnimationHandler存取使用了ThreadLocal,激起了我很大的好奇心以及兴趣 ...
- C#多线程之线程池篇3
在上一篇C#多线程之线程池篇2中,我们主要学习了线程池和并行度以及如何实现取消选项的相关知识.在这一篇中,我们主要学习如何使用等待句柄和超时.使用计时器和使用BackgroundWorker组件的相关 ...
- C#多线程之线程池篇2
在上一篇C#多线程之线程池篇1中,我们主要学习了如何在线程池中调用委托以及如何在线程池中执行异步操作,在这篇中,我们将学习线程池和并行度.实现取消选项的相关知识. 三.线程池和并行度 在这一小节中,我 ...
- C#多线程之线程池篇1
在C#多线程之线程池篇中,我们将学习多线程访问共享资源的一些通用的技术,我们将学习到以下知识点: 在线程池中调用委托 在线程池中执行异步操作 线程池和并行度 实现取消选项 使用等待句柄和超时 使用计时 ...
随机推荐
- canvas变换
canvas变换 方法 save() 保存canvas状态 restore() 回复canvas保存的状态 translate(x, y) 移动canvas位置 rotate(radians) 顺时针 ...
- ModuleNotFoundError: No module named '_sqlite3'
ModuleNotFoundError: No module named '_sqlite3' 解决: 1,首先安装 sqlite-devel yum install sqlite-devel 2,重 ...
- django多对多数据库建立 以及数据的传输 并进行增加 删除 修改
多对多数据库的建立 class Host(models.Model): nid = models.AutoField(primary_key=True) #自增id hostname = models ...
- AABB和平面的相交性检测
[AABB和平面的相交性检测]
- nginx反向代理同一主机多个网站域名
nginx反向代理同一ip多个域名,给header加上host就可以了 proxy_set_header Host $host; nginx.conf例子 upstream ...
- Python_05-文件操作
目录: 1 文件操作 1.1 快速入门 1.1.1 用Python创建一个新文件 1.1.2 文件内容追加,从0到9的10个随机整数 ...
- for 续6
---------siwuxie095 for 实际运用样例(/f 的使用不列出来): for %%i in (*) do echo %%i 显示当前目录下 ,所有非文 ...
- java替换特殊字符串
开始想到String.replaceFirst(regex, replacement)和String.replaceAll(regex, replacement); 但特殊字符没替换成功. 用法:St ...
- Kafka命令行常用命令说明
基于0.8.0版本. ##查看topic分布情况kafka-list-topic.sh bin/kafka-list-topic.sh --zookeeper 192.168.197.170:2181 ...
- Windows pip安装失败:no module named pkg_resources
通常是Setuptools安装出错,下载以下ez_setup.py文件后,先执行:ez_setup.py -U setuptools 重新安装setuptools 通过此ez_setup.py pip ...