zoukankan      html  css  js  c++  java
  • c#线程1

    开启一个线程的方式:

    方式一:Thread t1 = new Thread(Method_1);
                t1.Start();
    方式二:委托
                Action ac = Method_1;
                ac.BeginInvoke(null, null);

    线程其实就是操作系统中提到更加小的运行单元,比如一个进程可以存在多个线程,线程的执行不一定按顺序,并且从外部看来是同时进行的。

    我们举一个线程的一般定义,当然在定义之前需要先导入线程命名空间    using System.Threading;

        class Demo1
        {
            public void Method_1()
            {
                for (int i = 0; i < 100; i++)
                {
                    Console.WriteLine("我是线程1");
                }
            }
    
            public void Method_2()
            {
                for (int i = 0; i < 100; i++)
                {
                    Console.WriteLine("我是线程2");
                }
            }
    
            public void Test()
            {
                Thread t1 = new Thread(Method_1);
                t1.Start();
    
                Thread t2 = new Thread(Method_2);
                t2.Start();
            }
    
           static void Main(string[] args)
            {
                Demo1 obj = new Demo1();
                obj.Test();
            }

    如果对于某一个线程比较简单,可以使用Lamda表达式

            public void Test1()
            {
                Thread t1 = new Thread(
                    () =>
                    {
                        for (int i = 0; i < 100; i++)
                        {
                            Console.WriteLine("我是线程1");
                        }
                    }
                    );
                t1.Start();
    
                 Thread t2 = new Thread(
                    () =>
                    {
                        for (int i = 0; i < 100; i++)
                        {
                            Console.WriteLine("我是线程2");
                        }
                    }
                   );
                 t2.Start();
            }
    
            static void Main(string[] args)
            {
                Demo1 obj = new Demo1();
                obj.Test1();
            }

    线程中的方法不止上文的,它本身有3个重载方法,接下来是线程传递一个参数的例子:

            public void LoadDownFile(object fileName)
            {
                Console.WriteLine("文件名:"+fileName.ToString());
                Console.WriteLine("文件下载:"+Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(1000);
                Console.WriteLine("下载完毕");
            }
    
            public void Test2()
            {
                Thread t = new Thread(LoadDownFile);
                t.Start("abc.mov");
            }

    线程传递多个参数,在构造函数传递多个参数。

         public class ThreadTest
        {
            private string _FilePath;
            private string _FileName;
    
            public ThreadTest(string filePath,string fileName)
            {
                _FilePath = filePath;
                _FileName = fileName;
            }
    
            public void DownLoadFile()
            {
                Console.WriteLine("开始下载"+_FileName+"//"+_FilePath);
                Thread.Sleep(3000);
                Console.WriteLine("下载完毕");
            }
        }
            public void Test3()
            {
                ThreadTest thObj = new ThreadTest("伤心的人别听慢歌","你呀你我说你什么好");
                Thread t1 = new Thread(thObj.DownLoadFile);
                t1.Start();
            }

    委托开启线程,委托开启的线程是后台线程,需要加Console.ReadLine()要求主线程不关闭,知道后台线程运行完毕。

            public void Test4()
            {
                Action ac = Method_1;
                ac.BeginInvoke(null, null);
                Console.ReadLine();
            }
    
            public void Test5()
            {
                Action<int> ac = Method_3;
                ac.BeginInvoke(100, null, null);
                Console.ReadLine();
            }

    为了解决主线程不等待后台线程的情况,可以接收一个线程的返回值,进而判断其是否运行完成。

            public int LoadMoreFile(int num)
            {
                Console.WriteLine("正在下载");
                Thread.Sleep(1000);
                return num;
            }
    
    
            public void Test6()
            {
                Func<int, int> fu = LoadMoreFile;
    #异步调用状态 IAsyncResult result
    = fu.BeginInvoke(100, null, null); while (!result.IsCompleted) { Console.Write("."); } int intResult = fu.EndInvoke(result); Console.WriteLine("线程返回的数值:"+intResult); Console.ReadLine();这里不需要加,因为主线程会等待后台线程结束后退出 }

    使用回调函数实现线程异步:

            public void Test7()
            {
                Console.WriteLine("使用回调函数的方式");
                Func<int, int> fu = LoadMoreFile;
                fu.BeginInvoke(200, OnCallBack, fu);
                //主线程继续执行,当子线程结束自动回调,实现异步提高CPU效率
                //..........
                Console.ReadLine();
            }
    
            //OnCallBack()是回调函数,当子线程结束时,自动调用
            public void OnCallBack(IAsyncResult ar)
            {
                Func<int, int> res = ar.AsyncState as Func<int, int>;
                int intResult = res.EndInvoke(ar);
                Console.WriteLine("在回调函数中的结果:"+intResult);
            }

    线程设置其中的优先级:5中优先级,Highest、AblowNormai、Normal、BelowNormal、Lowest。

            public void Test()
            {
                Thread t1 = new Thread(Method_1);
                Thread t2 = new Thread(Method_2);
                Thread t3 = new Thread(Method_3);
                t1.Start();
                t2.Start();
                t3.Start();
    
                t1.Priority = ThreadPriority.Highest;
                t2.Priority = ThreadPriority.BelowNormal;
                t3.Priority = ThreadPriority.Lowest;
            }

    前台线程和后台线程:

    前台线程:主线程和Thread构造的线程都是前台线程,前台线程可以修改为后台线程t.IsBackgound()

    后台线程:比如之前通过委托构造的线程,Begin***为后台线程

    需要注意一点的是:后台线程会随着前台线程的结束而关闭,也就说前台线程必须完成,而后台线程则会选择性关闭。

            public void SleepTime()
            {
                Console.WriteLine("开始执行");
                Thread.Sleep(3000);
                Console.WriteLine("执行完毕");
            }
    
    
            public void Test2()
            {
                Thread t = new Thread(SleepTime);
                t.Start();
                t.IsBackground = true;
                Console.ReadLine();
            }
  • 相关阅读:
    建立表空间和用户
    数据库设计的基本步骤
    ubuntu21.04(linux):安装python3+dlib+face_recognition
    ubuntu21.04(linux):为chrome安装vue-devtools(6.0.0 beta 14)调试插件
    ubuntu21.04(linux):安装node(14.17.1)和vue.js3.1环境
    ubuntu21.04(linux):用apt安装nginx/php/mysql/phpmyadmin(开发环境)
    ubuntu21.04(linux):安装webstorm2021.1
    linux:在fedora 32/ubuntu 21.04安装chrome 90浏览器
    spring boot单元测试之十六:junit5:用@Timeout注解判断测试运行是否超时(spring boot 2.4.4)
    spring boot单元测试之十五:用mockmvc测试返回异步结果的controller(spring boot 2.4.4)
  • 原文地址:https://www.cnblogs.com/Optimism/p/10502795.html
Copyright © 2011-2022 走看看