.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             }
原文地址:https://www.cnblogs.com/yaopengfei/p/7071507.html