前面讲到了,直接使用Thread来运行代码,每次都会创建一个新的线程,如果频繁运行会带来不小的性能损耗,可以通过线程池来解决这个问题。
Thread每次都是新线程示例
示例代码
using System;
using System.Collections.Generic;
using System.Threading;
namespace ThreadDemo1Start
{
class Program
{
const int Count = 100;
static void Main(string[] args)
{
List<Thread> threads = new List<Thread>();
for (var i = 0; i < 10; i++)
{
//指定要在新线程中运行的代码,将在控制台中输出数字
ParameterizedThreadStart threadStart = DoWork;
//创建一个新的线程实例
Thread thread = new Thread(threadStart);
//开始运行新的线程实例
thread.Start(i.ToString());
threads.Add(thread);
}
//此处的代码不会被上面的start阻塞,是会同时运行的
//在控制台中输出-号
DoWork("-");
//等待线程执行完成
foreach(Thread thread in threads)
{
thread.Join();
}
//全部执行完毕
Console.WriteLine("全部执行完毕");
}
static void DoWork(object? obj)
{
//这里输出一下运行当前代码的线程的id,以便区分是否是新线程还是相同的线程
string str = $"{Thread.CurrentThread.ManagedThreadId}*{obj} ";
for(var i = 0; i < Count; i++)
{
Console.Write(str);
}
}
}
}
示例结果
从上面的运行结果可以看出,61,72,83,94,105,116,127,138,14*9。所有线程的id都是不相同的。
线程池
示例代码
using System;
using System.Collections.Generic;
using System.Threading;
namespace ThreadDemo1Start
{
class Program
{
const int Count = 100;
static void Main(string[] args)
{
for (var i = 0; i < 10; i++)
{
//使用线程池来运行所有的
ThreadPool.QueueUserWorkItem(DoWork, i.ToString());
}
//此处的代码不会被上面的start阻塞,是会同时运行的
//在控制台中输出-号
DoWork("-");
//使用线程池是不知道线程池的任务什么时候会执行完成的,此处先睡眠一段时间,等待执行完成
Thread.Sleep(TimeSpan.FromSeconds(3));
//全部执行完毕
Console.WriteLine("全部执行完毕");
}
static void DoWork(object? obj)
{
string str = $"{Thread.CurrentThread.ManagedThreadId}*{obj} ";
for(var i = 0; i < Count; i++)
{
Console.Write(str);
}
}
}
}
示例结果
从上面的运行结果可以看出,60,71 , 52,43 , 44,65,5*6。可以看出,输出3,4的是相同的线程,输出0,5的也是相同的线程,输出2,6的也是相同的线程。