.NET多线程之Thread、Task、ThreadPool、Timer
下表为多线程操作常见对象:
对象 | 方法/属性 | 描述 | 用途 | 用法 | 性能 |
Thread(线程) | Start | 启动线程,启动后线程处于System.Threading.ThreadState.Running状态 | 创建线程后,启动 | new Thread(()=>{}).Start(); | 中 |
Sleep | 将当前线程挂起指定的毫秒数。 | 挂起当前线程1秒 | Thread.Sleet(1000) | ||
Abort | 中止当前线程 | 停止后续代码运行 | Thread.CurrentThread.Abort() | ||
CurrentThread | 获取当前线程对象 | 获取当前线程对象 | Thread.CurrentThread | ||
CurrentPrincipal | 获取或设置线程的当前负责人(对基于角色的安全性而言)。 | 可通过ClaimsPrincipal在当前线程中存储相关申明,Abp中的DefaultPrincipalAccessor(IPrincipalAccessor)用来传递当前登陆人信息 | Thread.CurrentThread.ManagedThreadId | ||
ManagedThreadId | 获取当前托管线程的唯一标识符。 | ||||
Task(任务) | Run | 将在线程池上运行的指定工作排队,并返回 function 所返回的任务的代理项。 | Task.Run(()=>{}) | 高 | |
Delay | 创建一个在指定的时间间隔后完成的任务。 | Task.Delay(1000). | |||
WaitAll | 等待提供的所有 System.Threading.Tasks.Task 对象完成执行过程。 | 等待指定Task完成 | Task.WaitAll() | ||
WaitAny | 等待提供的任一 System.Threading.Tasks.Task 对象完成执行过程。 | 等待任一一个任务完成即执行后续操作 | Task.WaitAny() | ||
FromResult | 创建成功完成返回指定结果的任务 | 在异步开发模式中,常用于返回一个成功的任务,以达到异步调用的方式 | Task.FromResult(TResult) | ||
Task<TResult> | Result | 获取此Task返回值 | |||
ThreadPool(线程池) | QueueUserWorkItem | 将方法排入队列以便执行,并指定包含该方法所用数据的对象。 此方法在有线程池线程变得可用时执行。 |
object data = null; }, data); |
高 |
|
System.Timers.Timer(定时器),是对System.Threading.Timer封装 | Start | 通过将 System.Timers.Timer.Enabled 设置为 true 开始引发 System.Timers.Timer.Elapsed 事件。 | 高 | ||
Stop | 通过将 System.Timers.Timer.Enabled 设置为 false 停止引发 System.Timers.Timer.Elapsed 事件。 | ||||
Close | 释放由 System.Timers.Timer 占用的资源。 | ||||
AutoReset |
获取或设置一个布尔值,该值指示 System.Timers.Timer 是否应只引发一次 System.Timers.Timer.Elapsed 事件((false) 或重复 (true))。 |
应设置为true | |||
Enabled | 获取或设置一个值,该值指示 System.Timers.Timer 是否应引发 System.Timers.Timer.Elapsed 事件。 | 应设置为true | |||
Interval | 获取或设置引发 System.Timers.Timer.Elapsed 事件的间隔(以毫秒为单位)。 | ||||
System.Threading.Timer(定时器) |
高 |
1、Thread(线程)
原生的线程对象,性能相对较低,无法共用现有线程。每次都会创建一个新的线程,涉及到线程的销毁、创建,所以性能相对较低。不建议使用;
示例:
1 public void TestThread() 2 { 3 var thread = new Thread(() => 4 { 5 Console.WriteLine($"3、Async Current Thread Id={Thread.CurrentThread.ManagedThreadId.ToString("00")} Thread State={Thread.CurrentThread.ThreadState.ToString()}"); 6 }); 7 Console.WriteLine($"1、Async Current Thread Id={Thread.CurrentThread.ManagedThreadId.ToString("00")} Thread State={thread.ThreadState.ToString()}"); 8 thread.Start(); 9 Console.WriteLine($"2、Async Current Thread Id={Thread.CurrentThread.ManagedThreadId.ToString("00")} Thread State={thread.ThreadState.ToString()}"); 10 Thread.Sleep(1000); 11 Console.WriteLine($"4、Async Current Thread Id={Thread.CurrentThread.ManagedThreadId.ToString("00")} Thread State={thread.ThreadState.ToString()}"); 12 Console.WriteLine(Thread.GetDomainID()); 13 }
2、Task(任务)
官方文档:https://docs.microsoft.com/zh-cn/dotnet/api/system.threading.tasks.task?view=netframework-4.7.2
Task是对ThreadPool的封装,支持等待,不直接创建线程和销毁线程,由ThreadPool管理创建和销毁。建议使用;
示例:
public void TestTask() { Console.WriteLine($"Async Current Thread Id={Thread.CurrentThread.ManagedThreadId}"); var tasks = new List<Task>(100); for (var i = 0; i < 10; i++) { RunTask(i); } } private Task RunTask(int i) { return Task.Run(() => { Console.WriteLine($"Sync Current Thread Id={Thread.CurrentThread.ManagedThreadId.ToString("00")} i={i.ToString("00")}"); }); }
3、ThreadPool(线程池)
官方文档:https://docs.microsoft.com/zh-cn/dotnet/api/system.threading.threadpool?view=netframework-4.7.2
类似与ADO.NET数据库连接池,出发点都是用于统一管理线程的创建和销毁。如果异步任务不需要等待建议使用;
示例:
public void TestThreadPool() { object data = null; ThreadPool.QueueUserWorkItem((state) => { Console.WriteLine($"Sync Current Thread Id={Thread.CurrentThread.ManagedThreadId.ToString("00")} i={i.ToString("00")}"); }, data); }
4、System.Timers.Timer定时器
System.Threading.Timer官方文档:https://docs.microsoft.com/zh-cn/dotnet/api/system.threading.timer?view=netframework-4.7.2
System.Timers.Timer官方文档:https://docs.microsoft.com/zh-cn/dotnet/api/system.timers.timer?view=netframework-4.7.2
System.Timers.Timer定时器是对System.Threading.Timer封装,更加方便使用,使用那个看个人习惯;
示例:
public void TestTimer() { var hubTimer = new System.Timers.Timer(10 * 1000) { AutoReset = true, Enabled = true, }; hubTimer.Elapsed += Run;//注册事件 hubTimer.Elapsed -= Run;//取消事件 hubTimer.Start(); } public void Run(object sender, ElapsedEventArgs e) { }