//1 thread:线程等待,回调,前台线程/后台线程
//2 threadpool:线程池使用,设置线程池,ManualResetEvent
//3 扩展封装thread&threadpool回调/等待
class Program
{
static void Main(string[] args)
{
//ThreadTest threadTest = new ThreadTest();
//threadTest.ThreadShow();
ThreadPoolTest threadPoolTest = new ThreadPoolTest();
threadPoolTest.ThreadPoolShow();
Console.ReadLine();
}
}
/// 多线程1.0
/// Thread:C#对线程对象的一个封装
public class ThreadTest
{
public void ThreadShow()
{
Console.WriteLine($"**************** Start {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");
//{
// //执行无参数的委托
// ThreadStart method = () =>
// {
// DoSomething.DoSomethingLong("张三");
// };
// Thread thread = new Thread(method);
// thread.Start(); ;//开启线程,执行委托的内容
// //thread.Suspend(); //已启用,暂停线程
// //thread.Resume(); //已弃用,恢复线程
// //thread.Abort(); //停止线程 线程是计算机资源,程序想停下线程,只能向操作系统通知(线程抛异常),会有延时/不一定能真的停下来
// //1.等待
// //while (thread.ThreadState != ThreadState.Stopped) //根据线程状态判断
// //{
// // Thread.Sleep(200);//当前线程休息200ms
// //}
// //2.Join等待
// //thread.Join();
// //thread.Join(1000);//最多等待1000ms
// //Console.WriteLine("线程完成之后的操作");
// //thread.Priority = ThreadPriority.Highest;
// //最高优先级:优先执行,但不代表优先完成 甚至说极端情况下,还有意外发生,不能通过这个来控制线程的执行先后顺序
// // thread.IsBackground = false;//默认是false 前台线程,进程关闭,线程需要计算完后才退出
// // thread.IsBackground = true;//关闭进程,线程退出
//}
//{
// //执行带参数的委托
// ParameterizedThreadStart method = (o) =>
// {
// DoSomething.DoSomethingLong(o.ToString());
// };
// Thread thread = new Thread(method);
// thread.Start("张三"); ;//开启线程,执行委托的内容
//}
//Action action = () =>
//{
// Thread.Sleep(2000);
// Console.WriteLine("线程执行完回调方法");
//};
//ThreadStart method = () =>
//{
// DoSomething.DoSomethingLong("张三");
//};
//this.ThreadWithCallBack(method, action);
Func<int> method = () =>
{
Thread.Sleep(2000);
return 123;
};
Func<int> funcThread = this.ThreadWithReturn(method);//非阻塞
//Console.WriteLine("do something else/////");
//Console.WriteLine("do something else/////");
//Console.WriteLine("do something else/////");
//Console.WriteLine("do something else/////");
//Console.WriteLine("do something else/////");
int iResult = funcThread.Invoke();//当获取值的时候会阻塞
Console.WriteLine(iResult);
Console.WriteLine($"**************** End {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");
}
//基于thread封装一个回调
//回调:启动子线程执行动作A--不阻塞--A执行完后子线程会执行动作B
/// <summary>
///
/// </summary>
/// <param name="threadStart">多线程执行的操作</param>
/// <param name="actionCallback">线程完成后,回调的动作</param>
public void ThreadWithCallBack(ThreadStart threadStart, Action actionCallback)
{
ThreadStart start = new ThreadStart(() =>
{
threadStart.Invoke();
actionCallback.Invoke();
});
new Thread(start).Start();
}
/// <summary>
/// 1 异步,非阻塞的
/// 2 还能获取到最终计算结果
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="func"></param>
/// <returns></returns>
private Func<T> ThreadWithReturn<T>(Func<T> func)
{
T t = default(T);
ThreadStart start = new ThreadStart(() =>
{
t = func.Invoke();
});
Thread thread = new Thread(start);
thread.Start();
return new Func<T>(() =>
{
thread.Join();
return t;
});
}
}
///
/// 线程池.NetFramework2.0
/// 如果某个对象创建和销毁代价比较高,同时这个对象还可以反复使用的,就需要一个池子
/// 保存多个这样的对象,需要用的时候从池子里面获取;用完之后不用销毁,放回池子
/// 节约资源提升性能;此外,还能管控总数量,防止滥用;
///
/// ThreadPool的线程都是后台线程
///
public class ThreadPoolTest
{
public void ThreadPoolShow()
{
//开启线程执行委托
//ThreadPool.QueueUserWorkItem(o =>
//{
// Console.WriteLine("123");
//});
//ThreadPool.GetMaxThreads(out int workerThreads, out int completionPortThreads);
//Console.WriteLine($"当前电脑最大workerThreads={workerThreads} 最大completionPortThreads={completionPortThreads}");
//ThreadPool.GetMinThreads(out int workerThreadsMin, out int completionPortThreadsMin);
//Console.WriteLine($"当前电脑最小workerThreads={workerThreadsMin} 最大completionPortThreads={completionPortThreadsMin}");
////设置的线程池数量是进程全局的,
////委托异步调用--Task--Parrallel--async/await 全部都是线程池的线程
////直接new Thread不受这个数量限制的(但是会占用线程池的线程数量) 如果线程池数量已用完还是可以new Thread,如果先new Thread 会占用线程池数量
//ThreadPool.SetMaxThreads(8, 8);//设置的最大值,必须大于CPU核数,否则设置无效
//ThreadPool.SetMinThreads(2, 2);
//Console.WriteLine("&&&&&&&&&&&&&&&&&&&&&&&设置最大最小&&&&&&&&&&&&&&&&&&&&&&&&&&&");
//ThreadPool.GetMaxThreads(out int workerThreads1, out int completionPortThreads1);
//Console.WriteLine($"当前电脑最大workerThreads={workerThreads1} 最大completionPortThreads={completionPortThreads1}");
//ThreadPool.GetMinThreads(out int workerThreadsMin1, out int completionPortThreadsMin1);
//Console.WriteLine($"当前电脑最大workerThreads={workerThreadsMin1} 最大completionPortThreads={completionPortThreadsMin1}");
{
//等待
ManualResetEvent mre = new ManualResetEvent(false);
//false---关闭---Set打开---true---WaitOne就能通过
//true---打开--ReSet关闭---false--WaitOne就只能等待
ThreadPool.QueueUserWorkItem(o =>
{
DoSomething.DoSomethingLong("btnThreadPool_Click1");
mre.Set();
});
Console.WriteLine("Do Something else...");
Console.WriteLine("Do Something else...");
Console.WriteLine("Do Something else...");
mre.WaitOne();
Console.WriteLine("任务已经完成了。。。");
}
}
}