c# 线程的基本使用
2024-09-26 01:57:53
创建线程
线程的基本操作
线程和其它常见的类一样,有着很多属性和方法,参考下表:
创建线程的方法有很多种,这里我们先从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类型的。见下图:
最新文章
- iOS 原生态扫描二维码、条形码的功能。
- JS实现剪切板添加网站版权、来源
- c# as
- BZOJ 3192 删除物品(树状数组)
- Memcache入门知识
- 50个Android开发技巧(11 为文字加入特效)
- linux主机load average的概念&;&;计算过程&;&;注意事项
- 蓝桥杯-骰子游戏-java
- eclipse配置相关
- Let&#39;s Encrypt与DNS轮循
- java json转换(二)
- 算法 set / multiset -- lower_bound()的二分搜索
- qml:基本知识记录
- <;BEA-141281>; <;unable to get file lock, will retry ...>;
- ssh出错 sign_and_send_pubkey: signing failed: agent refused operation
- 轮廓的查找、表达、绘制、特性及匹配(How to Use Contour? Find, Component, Construct, Features &; Match)
- CSS样式属性——字体+文本
- htmlparser学习(原创)
- c#对一个类的扩展
- 猜数字游戏的提示(UVa340)
热门文章
- selenium+python在mac环境上的搭建
- Selenium Webdriver——实现截图功能
- msxml3.dll 执行页内操作时的错误
- 路由的分发include实现
- Spring Cloud Config配置中心的使用
- Python id() 函数
- 25.Reverse Nodes in k-Group (List)
- 使用透明flash+背景图片制作绚丽页面
- Visual Studio 2017 无法打开包括文件: “QOpenGLWidget”: No such file or directory
- 关于java项目中的.project文件: