C#多线程之基础篇1
在多线程这一系列文章中,我们将讲述C#语言中多线程的相关知识,在多线程(基础篇)中我们将学习以下知识点:
- 创建线程
- 中止线程
- 线程等待
- 终止线程
- 确定线程的状态
- 线程优先级
- 前台线程和后台线程
- 向线程传递参数
- 使用C#的lock关键字锁定线程
- 使用Monitor锁定线程
- 处理异常
一、创建线程
在整个系列文章中,我们主要使用Visual Studio 2015作为线程编程的主要工具。在C#语言中创建、使用线程只需要按以下步骤编写即可:
1、启动Visual Studio 2016,新建一个控制台应用程序。
2、确保该控制台程序使用.NET Framework 4.6或以上版本。然而在该篇中的所有示例使用较低版本可以正常工作。
3、双击打开该控制台应用程序中的“Program.cs”文件,在其中编写如下代码:
using System;
using System.Threading;
using static System.Console; namespace Recipe01
{
class Program
{
static void PrintNumbers()
{
WriteLine("Starting...");
for (int i = ; i < ; i++)
{
WriteLine(i);
}
} static void Main(string[] args)
{
Thread t = new Thread(PrintNumbers);
t.Start();
PrintNumbers();
}
}
}
4、运行该控制台应用程序,运行效果(每次运行效果可能不同)如下图所示:

在第2行代码处,我们导入了System.Threading命名空间,该命名空间包含了我们编写多线程程序所需要的所有类型。
在第3行代码处,我们使用了C# 6.0的using static特性,使用了该特性之后,在代码中允许我们在使用System.Console类型的静态方法的时候不需要指定其类型名。
在第9~16行代码处,我们定义了一个名为“PrintNumbers”的方法,该方法将在“Main”方法和线程中进行调用。
在第20行代码处,我们创建了一个线程来运行“PrintNumbers”方法,当我们初始化一个线程时,一个“ThreadStart”或“ParameterizedThreadStart”委托的实例被传递给线程的构造方法。
在第21行代码处,我们启动线程。
在第22行代码处,我们在“Main”方法中调用“PrintNumbers”方法。
二、中止线程
在这一节,我们将让线程等待一些时间,在等待的这段时间内,该线程不会消耗操作系统的资源。编写步骤如下:
1、使用Visual Studio 2015创建一个新的控制台应用程序。
2、双击打开“Program.cs”文件,编写代码如下所示:
using System;
using System.Threading;
using static System.Console;
using static System.Threading.Thread; namespace Recipe02
{
class Program
{
static void PrintNumbers()
{
WriteLine("Starting..."); for(int i = ; i < ; i++)
{
WriteLine(i);
}
} static void PrintNumbersWithDelay()
{
WriteLine("Starting..."); for(int i = ; i < ; i++)
{
Sleep(TimeSpan.FromSeconds());
WriteLine(i);
}
} static void Main(string[] args)
{
Thread t = new Thread(PrintNumbersWithDelay);
t.Start();
PrintNumbers();
}
}
}
3、运行该控制台应用程序,运行效果(每次运行效果可能不同)如下图所示:

在第20~29行代码处,我们定义了一个新的方法“PrintNumbersWithDelay”,该方法将在我们新建的线程中运行。需要注意的是在第26行代码处,我们使用了“Thread”类的静态方法“Sleep”,该方法使得每次循环都会等待2秒钟执行。
在第33行代码处,我们创建一个新的线程来运行“PrintNumbersWithDelay”方法。
三、线程等待
在这一节中,我们将讲述如何在一个线程执行完毕后,再执行剩余的代码,要完成这个工作,我们不能使用Thread.Sleep方法,因为我们不知道另一个线程精确的执行时间。要使一个线程等待另一个线程执行完毕后再进行其他工作,只需要按下列步骤编写代码即可:
1、使用Visual Studio 2015创建一个新的控制台应用程序。
2、双击打开“Program.cs”文件,编写如下代码:
using System;
using System.Threading;
using static System.Console;
using static System.Threading.Thread; namespace Recipe03
{
class Program
{
static void PrintNumbersWithDelay()
{
WriteLine("Starting..."); for(int i = ; i < ; i++)
{
Sleep(TimeSpan.FromSeconds());
WriteLine(i);
}
} static void Main(string[] args)
{
WriteLine("Starting...");
Thread t = new Thread(PrintNumbersWithDelay);
t.Start();
t.Join();
WriteLine("Thread completed");
}
}
}
3、运行该控制台应用程序,运行效果如下图所示:

在第26行代码处,我们在“Main”方法中调用调用“t.Join”方法,该方法允许我们等待线程t执行完毕后,再执行“Main”方法中剩余的代码。有了该技术,我们可以同步两个线程的执行步骤。第一个线程等待第二个线程执行完毕后,再进行其他的工作,在第一个线程等待期间,第一个线程的状态为“bolcked”状态,和我们调用Thread.Sleep的状态一样。
四、终止线程
在这一节中,我们将讲述如何终止另一个线程的执行。步骤如下:
1、使用Visual Studio 2015创建一个新的控制台应用程序。
2、双击打开“Program.cs”文件,编写如下代码:
using System;
using System.Threading;
using static System.Console;
using static System.Threading.Thread; namespace Recipe04
{
class Program
{
static void PrintNumbers()
{
WriteLine("Starting..."); for (int i = ; i < ; i++)
{
WriteLine(i);
}
} static void PrintNumbersWithDelay()
{
WriteLine("Starting...");
for (int i = ; i < ; i++)
{
Sleep(TimeSpan.FromSeconds());
WriteLine(i);
}
} static void Main(string[] args)
{
WriteLine("Starting program...");
Thread t = new Thread(PrintNumbersWithDelay);
t.Start();
Thread.Sleep(TimeSpan.FromSeconds());
t.Abort();
WriteLine("A thread has been aborted");
t = new Thread(PrintNumbers);
t.Start();
PrintNumbers();
}
}
}
3、运行该控制台应用程序,运行效果(每次运行效果可能不同)如下图所示:

在第36行代码处,我们调用了“t.Abort”方法,该方法用于终止一个线程的执行。当Abort方法被调用时,会对目标线程注入“ThreadAbortException”异常,该异常将导致线程的终止,这是一种非常危险的操作,因为这个异常可能发生在任何时候,并有可能导致整个应用程序的销毁。因此,不推荐使用Abort方法来终止一个线程的执行,我们可以向线程提供一个“CancellationToken”对象来取消一个线程的执行,这个技术我们将在后续讲述。
未完待续!
C#多线程之基础篇1的更多相关文章
- C#多线程之基础篇3
在上一篇C#多线程之基础篇2中,我们主要讲述了确定线程的状态.线程优先级.前台线程和后台线程以及向线程传递参数的知识,在这一篇中我们将讲述如何使用C#的lock关键字锁定线程.使用Monitor锁定线 ...
- C#多线程之基础篇2
在上一篇C#多线程之基础篇1中,我们主要讲述了如何创建线程.中止线程.线程等待以及终止线程的相关知识,在本篇中我们继续讲述有关线程的一些知识. 五.确定线程的状态 在这一节中,我们将讲述如何查看一个线 ...
- Java多线程系列--“基础篇”11之 生产消费者问题
概要 本章,会对“生产/消费者问题”进行讨论.涉及到的内容包括:1. 生产/消费者模型2. 生产/消费者实现 转载请注明出处:http://www.cnblogs.com/skywang12345/p ...
- Java多线程系列--“基础篇”04之 synchronized关键字
概要 本章,会对synchronized关键字进行介绍.涉及到的内容包括:1. synchronized原理2. synchronized基本规则3. synchronized方法 和 synchro ...
- Java多线程系列--“基础篇”02之 常用的实现多线程的两种方式
概要 本章,我们学习“常用的实现多线程的2种方式”:Thread 和 Runnable.之所以说是常用的,是因为通过还可以通过java.util.concurrent包中的线程池来实现多线程.关于线程 ...
- Java多线程系列--“基础篇”03之 Thread中start()和run()的区别
概要 Thread类包含start()和run()方法,它们的区别是什么?本章将对此作出解答.本章内容包括:start() 和 run()的区别说明start() 和 run()的区别示例start( ...
- Java多线程系列--“基础篇”05之 线程等待与唤醒
概要 本章,会对线程等待/唤醒方法进行介绍.涉及到的内容包括:1. wait(), notify(), notifyAll()等方法介绍2. wait()和notify()3. wait(long t ...
- Java多线程系列--“基础篇”06之 线程让步
概要 本章,会对Thread中的线程让步方法yield()进行介绍.涉及到的内容包括:1. yield()介绍2. yield()示例3. yield() 与 wait()的比较 转载请注明出处:ht ...
- Java多线程系列--“基础篇”07之 线程休眠
概要 本章,会对Thread中sleep()方法进行介绍.涉及到的内容包括:1. sleep()介绍2. sleep()示例3. sleep() 与 wait()的比较 转载请注明出处:http:// ...
随机推荐
- OpenCASCADE AIS Manipulator
OpenCASCADE AIS Manipulator eryar@163.com Abstract. OpenCASCADE7.1.0 introduces new built-in interac ...
- Android数据加密之异或加密算法
前言: 这几天被公司临时拉到去做Android IM即时通信协议实现,大致看了下他们定的协议,由于之前没有参与,据说因服务器性能限制,只达成非明文传递,具体原因我不太清楚,不过这里用的加密方式是采用异 ...
- iOS开发之Masonry框架源码深度解析
Masonry是iOS在控件布局中经常使用的一个轻量级框架,Masonry让NSLayoutConstraint使用起来更为简洁.Masonry简化了NSLayoutConstraint的使用方式,让 ...
- 如何定位Oracle数据库被锁阻塞会话的根源
首先再次明确下,数据库因为要同时保证数据的并发性和一致性,所以操作有锁等待是正常的. 只有那些长时间没有提交或回滚的事物,阻塞了其他业务正常操作,才是需要去定位处理的. 1.单实例环境 2.RAC环境 ...
- duang~免费的学习视频来啦:学霸君之全栈测试
学霸君向童鞋们推荐一款 同名学霸学习 视频教程 重点是完全免费收看学习噢!!! 今天 学霸君推荐腾讯课堂的学霸君之全栈测试 复制下方链接至腾讯课堂中报名学习 https://ke.qq.com/cou ...
- "NHibernate.Exceptions.GenericADOException: could not load an entity" 解决方案
今天,测试一个项目的时候,抛出了这个莫名其妙的异常,然后就开始了一天的调试之旅... 花了很长时间,没有从代码找出任何问题... 那么到底哪里出问题呢? 根据下面那段长长的错误日志: -- ::, ...
- ,net core mvc 文件上传
工作用到文件上传的功能,在这个分享下 ~~ Controller: public class PictureController : Controller { private IHostingEnvi ...
- C#泛型详解(转)
初步理解泛型: http://www.cnblogs.com/wilber2013/p/4291435.html 泛型中的类型约束和类型推断 http://www.cnblogs.com/wilber ...
- Android开发学习——画横线竖线
画横线/竖线 竖线 <View android:layout_width="1dp" android:layout_height="match_parent&quo ...
- Linux硬件IO的优化简介
Linux硬件IO的优化简介 首先简单介绍下有哪些硬件设备如下(由于硬件种类厂家等各种因素我就不在此多做介绍有兴趣的可以自行学习): 1.CPU:中央处理器,是计算机运算控制的核心部件之一,相当于人的 ...