一.Thread的使用方式

1.不带参数

(1)使用lambda

        public static void fun1()
{
Console.WriteLine($"Main ThreadId:{Thread.CurrentThread.ManagedThreadId}");
new Thread(new ThreadStart(() =>
{
Console.WriteLine($"Thread ThreadId:{Thread.CurrentThread.ManagedThreadId}");
})).Start();
}

  

(2)使用方法

        public static void ConsoleString()
{
Console.WriteLine($"Thread ThreadId:{Thread.CurrentThread.ManagedThreadId}");
} public static void fun2()
{
Console.WriteLine($"Main ThreadId:{Thread.CurrentThread.ManagedThreadId}");
new Thread(new ThreadStart(ConsoleString)).Start();
}

  

2.带参数(只允许带一个object类型参数)

        public static void fun3()
{
Console.WriteLine($"Main ThreadId:{Thread.CurrentThread.ManagedThreadId}");
new Thread(new ParameterizedThreadStart(t =>
{
Console.WriteLine($"{t} Thread ThreadId:{Thread.CurrentThread.ManagedThreadId}");
})).Start("haha");
}

  

3.等待线程执行

        public static void fun4()
{
Console.WriteLine($"Main start ThreadId:{Thread.CurrentThread.ManagedThreadId}");
Thread t = new Thread(new ThreadStart(() =>
{
Thread.Sleep(1000);
Console.WriteLine($"Thread ThreadId:{Thread.CurrentThread.ManagedThreadId}");
}));
t.Start();
t.Join();
Console.WriteLine($"Main end ThreadId:{Thread.CurrentThread.ManagedThreadId}");
}

  执行结果:

4.结束线程

Abort();

二.IsBackground讲解

thread.IsBackground=true:该线程为后台线程

thread.IsBackground=true:该线程为前台线程,Thread默认为前台线程

1.前台线程和后台线程的区别

  Net的公用语言运行时(Common Language Runtime,CLR)能区分两种不同类型的线程:前台线程和后台线程。这两者的区别就是:应用程序必须运行完所有的前台线程才可以退出;而对于后台线程,应用程序则可以不考虑其是否已经运行完毕而直接退出,所有的后台线程在应用程序退出时都会自动结束。

原理:只要所有前台线程都终止后,CLR就会对每一个活在的后台线程调用Abort()来彻底终止应用程序

2.使用建议

  对于一些在后台运行的线程,当程序结束时这些线程没有必要继续运行了,那么这些线程就应该设置为后台线程。比如一个程序启动了一个进行大量运算的线程,可是只要程序一旦结束,那个线程就失去了继续存在的意义,那么那个线程就该是作为后台线程的。而对于一些服务于用户界面的线程往往是要设置为前台线程的,因为即使程序的主线程结束了,其他的用户界面的线程很可能要继续存在来显示相关的信息,所以不能立即终止它们。这里我只是给出了一些原则,具体到实际的运用往往需要编程者的进一步仔细斟酌。
  一般后台线程用于处理时间较短的任务,如在一个Web服务器中可以利用后台线程来处理客户端发过来的请求信息。而前台线程一般用于处理需要长时间等待的任务,如在Web服务器中的监听客户端请求的程序,或是定时对某些系统资源进行扫描的程序。

3.示例

        public static void fun5()
{
Thread t1 = new Thread(new ThreadStart(() =>
{
for (int i = 0; i < 50; i++)
{
Thread.Sleep(100);
Console.WriteLine($"Thread1 {i} ThreadId:{Thread.CurrentThread.ManagedThreadId}");
}
}));
t1.Start(); Thread t2 = new Thread(new ThreadStart(() =>
{
for (int i = 0; i < 100; i++)
{
Thread.Sleep(100);
Console.WriteLine($"Thread2 {i} ThreadId:{Thread.CurrentThread.ManagedThreadId}");
}
}));
t2.IsBackground = true;
t2.Start();
}

  运行结果:

当t1执行完后,t2也不在执行,说明t1执行完成后,进程结束。

4.结束进程方式关联

private void fun()
{
Thread t1 = new Thread(new ThreadStart(() =>
{
for (int i = 0; i < 50; i++)
{
Thread.Sleep(1000);
Debug.WriteLine($"Thread1 {i} ThreadId:{Thread.CurrentThread.ManagedThreadId}");
}
}));
t1.Start(); Thread t2 = new Thread(new ThreadStart(() =>
{
for (int i = 0; i < 100; i++)
{
Thread.Sleep(1000);
Debug.WriteLine($"Thread2 {i} ThreadId:{Thread.CurrentThread.ManagedThreadId}");
}
}));
t2.IsBackground = true;
t2.Start();
}

  

(1)winform中:Application.Exit():所有线程都结束后(前台线程都结束后,后台线程自动结束),然后进程结束

执行 Application.Exit()

结果:等待t1执行完后,t2也不在执行,然后结束进程。

(2)Environment.Exit(0):不等待线程结束,直接结束进程

执行 Environment.Exit(0)

结果:直接结束进程,不等待线程。

参考:

https://blog.csdn.net/Fenglele_Fans/article/details/78555895

https://www.cnblogs.com/Again/articles/7085596.html

C#Thread学习的更多相关文章

  1. InnoDB master thread学习

    很久很久没有写博客了,工作比较忙,也没什么时间学习了,恰逢国庆放假,安心的学习一下,其实只是把之前学习过的知识再温习了一下而已.InnoDB 有众多的线程,其中非常核心的就是master thread ...

  2. thread学习笔记--BackgroundWorker 类

    背景: 在 WinForms 中,有时要执行耗时的操作,比如统计某个磁盘分区的文件夹或者文件数目,如果分区很大或者文件过多的话,处理不好就会造成“假死”的情况,或者报“线程间操作无效”的异常,或者在该 ...

  3. Thread学习

    1.定义 2.作用 3.和进程的比较 4.多线程(multithreading)的优点和缺陷 5.调度(scheduling) 6.线程相关概念 定义 线程就是最小的可编程指令序列,是进程的子集.一个 ...

  4. c++11: <thread>学习

    <thread>头文件中包含thread类与this_thread命名空间,下面逐一介绍. thread类 1. 构造函数 (1)默认构造函数 thread() noexcept; 默认构 ...

  5. Boost Thread学习笔记五

    多线程编程中还有一个重要的概念:Thread Local Store(TLS,线程局部存储),在boost中,TLS也被称作TSS,Thread Specific Storage.boost::thr ...

  6. Boost Thread学习笔记四

    barrierbarrier类的接口定义如下:  1 class barrier : private boost::noncopyable   // Exposition only 2 { 3 pub ...

  7. Boost Thread学习笔记三

    下面先对condition_impl进行简要分析.condition_impl在其构造函数中会创建两个Semaphore(信号量):m_gate.m_queue,及一个Mutex(互斥体,跟boost ...

  8. Boost Thread学习笔记二

    除了thread,boost种:boost::mutexboost::try_mutexboost::timed_mutexboost::recursive_mutexboost::recursive ...

  9. Boost Thread学习笔记

    thread自然是boost::thread库的主 角,但thread类的实现总体上是比较简单的,前面已经说过,thread只是一个跨平台的线程封装库,其中按照所使用的编译选项的不同,分别决定使用 W ...

  10. thread 学习

    #include <thread> #include <cstdio> #include <utility> #include <iostream> v ...

随机推荐

  1. linux字符界面下root用户无法登录成功

    os: rhel5.6_x86_64 ———————————————————————————————————————————— 故障:图形界面登录正常,其他一切正常,但是切换到字符界面时,输入用户ro ...

  2. 使用Revel(go)开发网站(全面版)

    Revel很好的利用了Go语言的goroutine,把每一个request都分配到了goroutine里.不用再写一大堆的回调.如果你写过nodejs的话就会深刻的体会到callback hell是什 ...

  3. Jenkins详细安装教程

    1.先下载msi文件 Jenkins下载链接: https://pan.baidu.com/s/1SACKNgW7OZrJoXMRDhsJxQ 提取码: 94b9 2.安装 解压后得到的是jenkin ...

  4. Mongodb时间问题

    Java保存到mongodb当前时间,使用RoboMongo查看数据显示时间比当前时间少8个小时,这是客户端的问题. MongoDB中的Date类型数据只保存绝对时间值,不保存时区信息,因此“显示的时 ...

  5. Oray.com花生壳路由器配置注意

    当路由器不链接wan口,只链接lan口时,此路由器其实就是当做一个无线交换机使用了,在此种情况下,花生壳登录会失败,因为花生壳本身也认为这设备不是路由器.

  6. leetcode872

    class Solution { public: vector<int> v1; vector<int> v2; void GetLeaf(TreeNode* tree, in ...

  7. JBPM具体应用之decision节点的使用

    JBPM工作流引擎为我们提供了许多的节点应用,每一个节点都有其不同的作用,其中有四个比较常用的节点,他们分别decision,fork,state和task.在本文中我们先介绍decision节点,余 ...

  8. RT2870移植到s3c2416后续验证无线…

    我的无线网卡显示的事ra0,所以把下面的wlan0换成ra0即可:视自己的情况而定 1. 打开无线网卡电源 iwconfig wlan0 txpower on 2. 列出区域内的无线网络 iwlist ...

  9. Xamarin官方示例代码无法部署,提示已跳过部署解决方法

    最近利用Visual Studio 2017学习Android开发.主要是通过Xamarin官方的文档进行的.官方的入门指导提供了很多的示例代码.但是下载之后,调试运行的时候,总是无法部署到虚拟机上. ...

  10. Enumeration & Class & Structure

    [Enumeration] 1.当一个枚举值类型已经确定后,可以使用shorter dot syntax来赋予其它值: 2.对一个枚举值switch的时候也可以使用short dot syntax: ...