• C#Thread学习


    一.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

  • 相关阅读:
    docker进入容器命令
    docker复制文件到容器内以及从容器内复制文件到宿主机
    在idea中创建maven父子工程,子工程无法导入父工程依赖的问题
    maven merge 其他分支比如master的方法
    Maven 右边的maven 项目为空 pom文件
    Spark Streaming集成Kafka调优
    spark sql/hive小文件问题
    CompletableFuture详解
    样式绑定styleBinding
    jsonArray图片数组实例
  • 原文地址:https://www.cnblogs.com/yaosj/p/10682580.html
Copyright © 2020-2023  润新知