C#(99):ThreadPool
2021-03-03 18:26
标签:back 空闲 表示 null user max stat 没有 RKE 提供一个线程池,该线程池可用于执行任务、发送工作项、处理异步 I/O、代表其他线程等待以及处理计时器。 创建线程需要时间。如果有不同的小任务要完成,就可以事先创建许多线程/在应完成这些任务时发出请求。不需要自己创建这样一个列表。该列表由ThreadPool类托管。 这个类会在需要时增减池中线程的线程数,直到最大的线程数。 如果有更多的作业要处理,线程池中线程的个数也达到了极限,最新的作业就要排队,且必须等待线程完成其任务。 池中的最大线程数是可配置的。在双核CPU中,默认设置为1023 个工作线程和1000个I/O线程。也可以指定在创建线程池时应立即启动的最小线程数,以及线程池 中可用的最大线程数。 将方法排入队列以便执行,并指定包含该方法所用数据的对象。 此方法在有线程池线程变得可用时执行。 实例: 注册一个等待 WaitHandle 的委托,并指定一个数来表示超时值(以毫秒为单位)。 将指定的方法排队到线程池,当超时或者等待委托接收到信号时,辅助线程将执行此方法,即主线程控制辅助线程什么时候开始执行。
结果如下: WaitProc( First task ) executes on thread 7; cause = TIMED OUT. C#(99):ThreadPool 标签:back 空闲 表示 null user max stat 没有 RKE 原文地址:https://www.cnblogs.com/springsnow/p/12976003.html一、ThreadPool概述
线程池使用起来很简单,但它有一些限制
使用线程池线程的操作的情况包括
二、方法
三、设置和获取线程数方法
int i = 0;
int j = 0;
//前面是辅助(也就是所谓的工作者)线程,后面是I/O线程
ThreadPool.GetMaxThreads(out i, out j);
Console.WriteLine(i.ToString() + " " + j.ToString()); //默认都是1000
//获取空闲线程,由于现在没有使用异步线程,所以为空
ThreadPool.GetAvailableThreads(out i, out j);
Console.WriteLine(i.ToString() + " " + j.ToString()); //默认都是1000
四、将方法排入队列以便执行:QueueUserWorkItem(WaitCallback, Object)
public static bool QueueUserWorkItem (System.Threading.WaitCallback callBack, object state);
static void Main(string[] args)
{
Person p = new Person(1, "刘备");
//启动工作者线程
ThreadPool.QueueUserWorkItem(new WaitCallback(RunWorkerThread), p);
}
static void RunWorkerThread(object obj)
{
Thread.Sleep(200);
Console.WriteLine("线程池线程开始!");
Person p = obj as Person;
Console.WriteLine(p.Name);
}
public class Person
{
public Person(int id, string name) { Id = id; Name = name; }
public int Id { get; set; }
public string Name { get; set; }
}
五、RegisterWaitForSingleObject 注册等待句柄
public static System.Threading.RegisteredWaitHandle RegisterWaitForSingleObject (System.Threading.WaitHandle waitObject, System.Threading.WaitOrTimerCallback callBack, object state, int millisecondsTimeOutInterval, bool executeOnlyOnce);
1、参数
如果为0(零),函数将测试对象的状态并立即返回。 如果为 -1,则函数的超时间隔永远不过期。表示间隔几秒执行回调方法,指当刚加入线程后,它是需要过了几秒后才会第一次执行回调方法。如果使用了wait.Set()方法使用立即执行回调函数而不需要等待。
2、返回
// TaskInfo contains data that will be passed to the callback method.
public class TaskInfo
{
public RegisteredWaitHandle Handle = null;
public string OtherInfo = "default";
}
public static void Main(string[] args)
{
// 主线程使用AutoResetEvent来给已注册的等待句柄发信号, 此等待句柄执行回调方法
AutoResetEvent ev = new AutoResetEvent(false);
TaskInfo ti = new TaskInfo();
ti.OtherInfo = "First task";
// 该任务的TaskInfo包括RegisterWaitForSingleObject返回的已注册的等待句柄。这允许在对象被发出一次信号时终止等待(参见WaitProc)。
ti.Handle = ThreadPool.RegisterWaitForSingleObject(
ev,
new WaitOrTimerCallback(WaitProc),
ti,
1000,
false
);
// 主线程等待三秒,为了演示队列中的线程超时,然后发信号.
Thread.Sleep(3100);
Console.WriteLine("Main thread signals.");
ev.Set();//发信号
// 主线程休眠,这应该给回调方法执行的时间。如果注释掉这一行,程序通常会在ThreadPool线程执行之前结束。
Thread.Sleep(1000);
/ /如果您自己启动一个线程,您可以通过调用thread . join来等待它结束。此选项在线程池线程中不可用。
}
//当注册的等待时间超时,或者WaitHandle(在本例中是AutoResetEvent)发出信号时,回调方法执行。WaitProc在事件第一次发出信号时注销WaitHandle。.
public static void WaitProc(object state, bool timedOut)
{
TaskInfo ti = (TaskInfo)state;
string cause = "TIMED OUT";
if (!timedOut) //如果Timeout为false,表示接收到的信号后执行的
{
cause = "SIGNALED";
//如果回调方法执行的话是因为WaitHandle触发信号的话,则用反注册等待句柄来取消回调方法将来的执行。
if (ti.Handle != null)
ti.Handle.Unregister(null);//
}
Console.WriteLine("WaitProc( {0} ) executes on thread {1}; cause = {2}.",
ti.OtherInfo, Thread.CurrentThread.GetHashCode().ToString(), cause);//超时后执行的
}
WaitProc( First task ) executes on thread 7; cause = TIMED OUT.
WaitProc( First task ) executes on thread 7; cause = TIMED OUT.
Main thread signals.
WaitProc( First task ) executes on thread 7; cause = SIGNALED.