一.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. EM64T和64位是不是一个概念啊?他们有什么区别啊,怎么区分啊?

    首先我们要解决什么是64位这个问题.究竟什么是64位处理器呢?64 bit是相对于32 Bit而言的,这个位数指的是CPU GPRs(General-Purpose Registers,通用寄存器)数 ...

  2. 利用ffmpeg一步一步编程实现摄像头采集编码推流直播系统

    了解过ffmpeg的人都知道,利用ffmpeg命令即可实现将电脑中摄像头的画面发布出去,例如发布为UDP,RTP,RTMP等,甚至可以发布为HLS,将m3u8文件和视频ts片段保存至Web服务器,普通 ...

  3. java图形用户界面BorderLayout布局。冲突

    总结:在使用边界布局发现,把所有的按钮组件都放入了panel.但是在中部的按钮组件找不到了.发现自己重复用了组件 1.this.add(bt4,BorderLayout.North); 2.panel ...

  4. MySQL存储过程中的3种循环,存储过程的基本语法,ORACLE与MYSQL的存储过程/函数的使用区别,退出存储过程方法

    在MySQL存储过程的语句中有三个标准的循环方式:WHILE循环,LOOP循环以及REPEAT循环.还有一种非标准的循环方式:GOTO,不过这种循环方式最好别用,很容易引起程序的混乱,在这里就不错具体 ...

  5. nginx 的第三方模块ngx_http_accesskey_module 来实现下载文件的防盗链步骤(linux系统下)

    nginx 的第三方模块ngx_http_accesskey_module 来实现下载文件的防盗链步骤(linux系统下),安装Nginx和HttpAccessKeyModule模块(参考LNMP环境 ...

  6. mysql函数之六:mysql插入数据后返回自增ID的方法,last_insert_id(),selectkey

    mysql插入数据后返回自增ID的方法 mysql和oracle插入的时候有一个很大的区别是,oracle支持序列做id,mysql本身有一个列可以做自增长字段,mysql在插入一条数据后,如何能获得 ...

  7. WIN10运行软件,窗口不显示(移动到屏幕外无法复原)的解决办法 Lebal:bug10解决方案

    双显示器切换回单显示器的时候,可能会遇到窗口移动到屏幕外不显示的情况 像这样虽然有缩略图但是点击无反应,并且平铺窗口也不管用,这个时候单击该窗口,Alt+space 执行最小化以及最大化操作即可复原

  8. 转载:细说oracle 11g rac 的ip地址

    本文转载自:细说oracle 11g rac 的ip地址 http://blog.sina.com.cn/s/blog_4fe6d4250102v5fa.html 以前搭建oracle rac的时候( ...

  9. 优秀设计师必须知道哪些优秀的UI设计原则

    转自:http://www.gamelook.com.cn/2016/01/240359 界面清晰最重要 界面清晰是UI设计的第一步,要想让用户喜欢你设计的UI,首先必须让用户认可它.知道怎么样使用它 ...

  10. verilog 之语法学习

    1.使用非基数表示的十进制视为有符号数.使用基数表示的十进制被视为无符号数. 2.线网中的值被解释为无符号数,整型寄存器中的值被解释为有符号的二进制补码数,. 3.如果选择表达式的值为 x.z,或越界 ...