创建线程

线程的基本操作

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

创建线程的方法有很多种,这里我们先从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类型的。见下图:

最新文章

  1. iOS 原生态扫描二维码、条形码的功能。
  2. JS实现剪切板添加网站版权、来源
  3. c# as
  4. BZOJ 3192 删除物品(树状数组)
  5. Memcache入门知识
  6. 50个Android开发技巧(11 为文字加入特效)
  7. linux主机load average的概念&amp;&amp;计算过程&amp;&amp;注意事项
  8. 蓝桥杯-骰子游戏-java
  9. eclipse配置相关
  10. Let&#39;s Encrypt与DNS轮循
  11. java json转换(二)
  12. 算法 set / multiset -- lower_bound()的二分搜索
  13. qml:基本知识记录
  14. &lt;BEA-141281&gt; &lt;unable to get file lock, will retry ...&gt;
  15. ssh出错 sign_and_send_pubkey: signing failed: agent refused operation
  16. 轮廓的查找、表达、绘制、特性及匹配(How to Use Contour? Find, Component, Construct, Features &amp; Match)
  17. CSS样式属性——字体+文本
  18. htmlparser学习(原创)
  19. c#对一个类的扩展
  20. 猜数字游戏的提示(UVa340)

热门文章

  1. selenium+python在mac环境上的搭建
  2. Selenium Webdriver——实现截图功能
  3. msxml3.dll 执行页内操作时的错误
  4. 路由的分发include实现
  5. Spring Cloud Config配置中心的使用
  6. Python id() 函数
  7. 25.Reverse Nodes in k-Group (List)
  8. 使用透明flash+背景图片制作绚丽页面
  9. Visual Studio 2017 无法打开包括文件: “QOpenGLWidget”: No such file or directory
  10. 关于java项目中的.project文件: