文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

C#多线程之线程池ThreadPool详解

2024-04-02 19:55

关注

一、ThreadPool概述

提供一个线程池,该线程池可用于执行任务、发送工作项、处理异步 I/O、代表其他线程等待以及处理计时器。

创建线程需要时间。如果有不同的小任务要完成,就可以事先创建许多线程/在应完成这些任务时发出请求。不需要自己创建这样一个列表。该列表由ThreadPool类托管。

这个类会在需要时增减池中线程的线程数,直到最大的线程数。池中的最大线程数是可配置的。在双核CPU中,默认设置为1023 个工作线程和1000个I/O线程。也可以指定在创建线程池时应立即启动的最小线程数,以及线程池 中可用的最大线程数。

如果有更多的作业要处理,线程池中线程的个数也达到了极限,最新的作业就要排队,且必须等待线程完成其任务。

线程池使用起来很简单,但它有一些限制:

使用线程池线程的操作的情况包括:

二、方法

三、获取线程数方法

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 注册等待句柄

注册一个等待 WaitHandle 的委托,并指定一个数来表示超时值(以毫秒为单位)。

将指定的方法排队到线程池,当超时或者等待委托接收到信号时,辅助线程将执行此方法,即主线程控制辅助线程什么时候开始执行。

public static System.Threading.RegisteredWaitHandle RegisterWaitForSingleObject (System.Threading.WaitHandle waitObject, System.Threading.WaitOrTimerCallback callBack, object state, int millisecondsTimeOutInterval, bool executeOnlyOnce);

参数

返回

// 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";
    // The TaskInfo for the task includes the registered wait handle returned by RegisterWaitForSingleObject.  This
    // allows the wait to be terminated when the object has been signaled once (see WaitProc).
    ti.Handle = ThreadPool.RegisterWaitForSingleObject(
        ev,
        new WaitOrTimerCallback(WaitProc),
        ti,
        1000,
        false
    );

    // 主线程等待三秒,为了演示队列中的线程超时,然后发信号.
    Thread.Sleep(3100);
    Console.WriteLine("Main thread signals.");
    ev.Set();//发信号

    // The main thread sleeps, which should give the callback method time to execute.  If you comment out this line, the program usually ends before the ThreadPool thread can execute.
    Thread.Sleep(1000);
    // If you start a thread yourself, you can wait for it to end by calling Thread.Join.  This option is not available with  thread pool threads.
}

//The callback method executes when the registered wait times out, 
//or when the WaitHandle (in this case AutoResetEvent) is signaled. 
//WaitProc unregisters the WaitHandle the first time the event is  signaled.
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.
WaitProc( First task ) executes on thread 7; cause = TIMED OUT.
Main thread signals.
WaitProc( First task ) executes on thread 7; cause = SIGNALED.

到此这篇关于C#多线程之线程池ThreadPool的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持编程网。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯