• .Net进阶系列(12)-异步多线程(Thread和ThreadPool)(被替换)


    一. Thread多线程

      1. 两种使用方式

      通过F12查看Thread后,发现有两类构造函数,ParameterizedThreadStart和ThreadStart,其中

        ThreadStart:无参无返回值的委托

        ParameterizedThreadStart:无返回值,但是有一个object类型参数的委托

          下面Thread的使用都是围绕上面这两个构造函数来进行的。

    方式一:(当委托是无参数,但赋值的方法又是有参数的,可以使用这种方式转换)

          当只有一行的时候,可以省略{},实际上和下面一个道理 

                {
                    ThreadStart tStart = () => TestThread("参数1", "参数2");
                    //ThreadStart tStart2 = () =>
                    //{
                    //    TestThread("参数1", "参数2");
                    //};
                    Thread thread = new Thread(tStart);
                    thread.Start();
                }

    方式二:(当委托是有一个object参数的时候, 如果赋值的方法不是只有一个参数,将不适用与该委托)不推荐这种方式,存在拆箱和装箱问题,效率低

     1             {
     2                 ParameterizedThreadStart pStart = t => TestThread2(t.ToString());
     3                 //ParameterizedThreadStart pStart2 = (t) => TestThread2(t.ToString());
     4                 //ParameterizedThreadStart pStart3 = (t) =>
     5                 //{
     6                 //    TestThread2(t.ToString());
     7                 //};
     8                 Thread thread = new Thread(pStart);
     9                 thread.Start("参数1");
    10             }

     2. 利用Join方法进行线程等待

     1  {
     2                 List<Thread> list = new List<Thread>();
     3                 for (int i = 0; i < 5; i++)
     4                 {
     5                     string name1 = string.Format("ypf1-{0}", i);
     6                     string name2 = string.Format("ypf2-{0}", i);
     7                     ThreadStart tStart = () => TestThread(name1, name2);
     8                     Thread thread = new Thread(tStart);
     9                     list.Add(thread);
    10                     thread.Start();
    11                 }
    12                 //线程等待
    13                 foreach (var item in list)
    14                 {
    15                     item.Join();
    16                 }
    17             }

     3. 补充:可以利用IsBackground设置是否为后台线程

    二. ThreadPool多线程

        1. 使用方式

           ThreadPool开启线程唯一的方式就是 ThreadPool.QueueUserWorkItem() ,QueueUserWorkItem的参数为WaitCallback,WaitCallback为有一个object类型参数的无返回值的委托,那么该委托将怎么应对,无参数函数、一个参数的函数、多个参数的函数。

     1         //1. 没有参数
     2             {
     3                 WaitCallback wcl = t => TestThread3();
     4                 ThreadPool.QueueUserWorkItem(wcl);
     5             }
     6             //2. 一个参数
     7             {
     8                 WaitCallback wcl = t => TestThread2(t.ToString());
     9                 ThreadPool.QueueUserWorkItem(wcl, "测试参数1");
    10             }
    11             //3. 两个参数
    12             {
    13                 //因为WaitCallback委托没法结束有两个参数的方法,这里我们采用将方法封装到类中的方式解决
    14                 MyTest<string, string> model = new MyTest<string, string>("测试参数1", "测试参数2");
    15                 WaitCallback wcl = (t) =>
    16                 {
    17                     model.TestThread();
    18                 };
    19                 ThreadPool.QueueUserWorkItem(wcl);
    20             }
     1  public class MyTest<T,M>
     2     {
     3         public T msg1 { get; set; }
     4         public M msg2 { get; set; }
     5         public MyTest(T t1,M m1)
     6         {
     7             this.msg1 = t1;
     8             this.msg2 = m1;
     9         }
    10         public  void TestThread()
    11         {
    12             Console.WriteLine("线程开始:测试参数为:{0}和{1},当前线程的id为:{2}", msg1, msg2, System.Threading.Thread.CurrentThread.ManagedThreadId);
    13             long sum = 0;
    14             for (int i = 1; i < 999999999; i++)
    15             {
    16                 sum += i;
    17             }
    18             Console.WriteLine("线程结束:测试参数为:{0}和{1},当前线程的id为:{2}", msg1, msg2, System.Threading.Thread.CurrentThread.ManagedThreadId);
    19         }
    20     }

      2. 多线程等待

     1        List<ManualResetEvent> list = new List<ManualResetEvent>();
     2             for (int i = 0; i < 5; i++)
     3             {
     4                 ManualResetEvent mr = new ManualResetEvent(false);
     5                 WaitCallback wcl = t =>
     6                 {
     7                     TestThread2(t.ToString());
     8                     mr.Set(); //将该线程设置为终止状态
     9                 };
    10                 list.Add(mr);
    11                 ThreadPool.QueueUserWorkItem(wcl, "测试参数1");
    12             }
    13             foreach (var item in list)
    14             {
    15                 item.WaitOne();
    16             }

      3. 线程池的基本设置

     1             {
     2                 //1.设置最大和最小线程数
     3                 ThreadPool.SetMaxThreads(8, 8);
     4                 ThreadPool.SetMinThreads(4, 4);
     5                 //2.工作线程和IO线程最大值和最小值的获取(注释掉上面的设置,然后看下面的获取结果)
     6                 int workerThreads;
     7                 int ioThreads;
     8                 {
     9                     ThreadPool.GetMaxThreads(out workerThreads, out ioThreads);
    10                     Console.WriteLine(String.Format("Max worker threads: {0};    Max I/O threads: {1}", workerThreads, ioThreads));
    11                 }
    12                 {
    13                     ThreadPool.GetMinThreads(out workerThreads, out ioThreads);
    14                     Console.WriteLine(String.Format("Min worker threads: {0};    Min I/O threads: {1}", workerThreads, ioThreads));
    15                 }
    16                 {
    17                     ThreadPool.GetAvailableThreads(out workerThreads, out ioThreads);
    18                     Console.WriteLine(String.Format("Available worker threads: {0};    Available I/O threads: {1}", workerThreads, ioThreads));
    19                 }
    20             }
  • 相关阅读:
    描述软件质量属性需求和质量属性场景(以淘宝网为例)
    软件架构初识
    机器学习实践02
    机器学习实践01
    机器学习十讲02
    用户故事与敏捷方法阅读笔记05
    机器学习十讲01
    用户故事与敏捷方法阅读笔记04
    tensorflow学习05(Mnist数据集)
    spring boot发送HTTP请求
  • 原文地址:https://www.cnblogs.com/yaopengfei/p/7071507.html
Copyright © 2020-2023  润新知