C#基础–线程Thread和线程池ThreadPool
一、线程 Thread
1. 开启一个线程
ThreadStart 是属于System.Threading 中的一个内置委托
ThreadStart threadStart = () =>
{
this.DoSomethingLong("btnThread_Click");
};
Thread thread = new Thread(threadStart); //传入委托
thread.Start(); //开启一个新线程
ParameterizedThreadStart 是属于System.Threading 中的一个内置委托
ParameterizedThreadStart threadStart = ar =>
{
this.DoSomethingLong("btnThread_Click");
};
Thread thread = new Thread(threadStart);
thread.Start(); //开启一个新线程
2. 暂停/恢复线程
无法实时的去 “暂停 ” 或者 “恢复” 线程,因为线程是由系统调度执行的,而且中间存在一个延时现象,不可能直接帮你执行
thread.Suspend(); // 暂停线程
thread.Resume(); //恢复 无法实时的去暂停或者恢复线程
3. 终结线程
在调用Abort()方法的线程上引发 System.Threading.ThreadAbortException,以开始终止此线程的过程。 调用此方法通常会终止线程。
Thread.ResetAbort() 也会存在一定的延迟问题
thread.Abort(); //终结线程
Thread.ResetAbort(); //终结的线程继续执行
4. 等待任务
根据线程状态等待
ThreadState 是一种枚举类型
while (thread.ThreadState != ThreadState.Stopped)
{
Thread.Sleep(200);
}
Join等待
限时等待,和委托中的 WaitOne等待 很像
thread.Join(); //无限时等待
thread.Join(2000); //最多等待2000毫秒
5. 线程调度优先级
Priority 是一种枚举类型,设置了的话只是增加它的优先概率,并不能一定能保证它实现正确的优先级执行(因为CPU是分核的)
thread.Priority = ThreadPriority.Highest;
6. 后台/前台线程
后台线程:进程结束,线程也结束;例如,winform 功能在控制台输出,关闭winform窗体,控制台窗口也会立即关闭
前台线程:进程结束后,任务执行完毕以后,线程才结束;例如,winform 功能在控制台输出,关闭winform窗体,控制台窗口只有等线程任务完成后才会关闭
thread.IsBackground = true; //后台线程 进程结束,线程结束了
thread.IsBackground = false; //前台线程 进程结束后,任务执行完毕以后,线程才结束
二、线程 Thread 扩展
1. 无返回结果
private void ThreadWithCallBack(ThreadStart threadStart, Action actionCallback)
{
ThreadStart threadStart = new ThreadStart(() =>
{
threadStart.Invoke();
actionCallback.Invoke();
});
Thread thread = new Thread(threadStart);
thread.Start();
}
ThreadStart threadStart1 = () =>
{
Console.WriteLine("执行任务");
};
Action action = () =>
{
Console.WriteLine("执行回调");
};
this.ThreadWithCallBack(threadStart1, action);
2. 开启一个线程,并获取返回结果
扩展方法内部开启一个线程执行任务 – 执行传入的委托
线程等待的工作封装到另外一个委托,将委托返回出去,让外部执行:这样就不会造成封装方法内阻塞(卡界面),调用封装方法的程序可以继续执行之后的代码
需要结果的时候,再去执行返回的委托;如果不需要的结果的话,就不必再去执行返回的委托了
/// <summary>
/// 既要不卡界面,又需要返回结果
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="func"></param>
/// <returns></returns>
private Func<T> ThreadWithReturn<T>(Func<T> func)
{
T t = default(T);
ThreadStart threadStart = new ThreadStart(() =>
{
t = func.Invoke();
});
Thread thread = new Thread(threadStart);
thread.Start();
return new Func<T>(() =>
{
thread.Join();
return t;
});
}
Func<int> func = () =>
{
Thread.Sleep(5000);
return DateTime.Now.Year;
};
Func<int> FuncResult = this.ThreadWithReturn(func);
Console.WriteLine("同步执行操作1--发短信");
Console.WriteLine("同步执行操作2--发邮件");
Console.WriteLine("同步执行操作3--统计信息");
Console.WriteLine("同步执行操作4--更新ES数据");
int iResult = FuncResult.Invoke(); //如果需要得到执行结果,是必须要等待的
三、线程池 ThreadPool
.NetFramework2.0 出现的
在Thread中对线程的管理需要我们自己去从操作,在不断的开启线程和销毁中,存在很大的开销,为了让线程可以反复的使用,出现了池化思想!
线程池不仅可以节省资源,还可以控制线程总数量,防止滥用!
1. 开启一个线程
ThreadPool.QueueUserWorkItem 需要传入一个WaitCallback委托作为参数
WaitCallback是 System.Threading 内置的一个委托
ThreadPool.QueueUserWorkItem(o =>
{
this.DoSomethingLong("ThreadPool.QueueUserWorkItem1"); //开启了一个线程
});
ThreadPool.QueueUserWorkItem(o =>
{
Console.WriteLine($"第二个参数:{o}");
this.DoSomethingLong("ThreadPool.QueueUserWorkItem1");//开启了一个线程
}, "Hyl");
2. 设置/获取 最大最小线程
设置线程数量是全局,线程池是全局,Task、async/awit 都是来自于线程,所以本人不建议大家随便设置!
设置线程最大数量的时候,数量不能低于本计算机的核数,否则设置无效。如下图效果图:(2047,1000 是默认设置)
ThreadPool.SetMaxThreads(2, 2); //这里在设置的时候,数量不能低于本计算机的 核数
ThreadPool.SetMinThreads(2, 2);
ThreadPool.GetMaxThreads(out int maxWorkerThreads1, out int maxCompletionPortThreads1);
ThreadPool.GetMinThreads(out int minWorkerThreads1, out int minCompletionPortThreads1);
Console.WriteLine($"当前电脑最大workerThreads={maxWorkerThreads1},最大的completionPortThreads={maxCompletionPortThreads1}");
Console.WriteLine($"当前电脑最小workerThreads={minWorkerThreads1},最小的completionPortThreads={minCompletionPortThreads1}");
文章来源:https://www.toymoban.com/news/detail-588508.html
3. 线程等待
ManualResetEvent manualResetEvent = new ManualResetEvent(false); //开关关闭
ThreadPool.QueueUserWorkItem(o =>
{
this.DoSomethingLong("btnThreadPool_Click1");
Thread.Sleep(3000);
manualResetEvent.Set();// 开关打开
});
manualResetEvent.WaitOne(); //执行到这儿来的时候,我就等你给我发信号
Console.WriteLine("计算完成");
文章来源地址https://www.toymoban.com/news/detail-588508.html
到了这里,关于C#基础--线程Thread和线程池ThreadPool的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!