怎么判断ThreadPool线程池里的任务都执行完毕
c# ThreadPool 判断子线程全部执行完毕的四种方法
1、先来看看这个
多线程编程
多线程用于数据采集时,速度明显很快,下面是基本方法,把那个auto写成采集数据方法即可。
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
try
{
ThreadPool.SetMaxThreads(3, 3); //设置最大线程数
for (int i = 0; i < 10; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(Auto), i);//线程池指定线程执行Auto方法
}
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public static void Auto(object i)//多线程执行的方法
{
if (string.Equals(i,2))
{
Thread.Sleep(2000);
}
Console.WriteLine(i.ToString());
}
}
}
明白吧,就是多线程执行顺序是不确定的。
2、再来看看这个结果
static void Main(string[] args)
{
try
{
ThreadPool.SetMaxThreads(3, 3); //设置最大线程数
for (int i = 0; i < 10; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(Auto), i);//线程池指定线程执行Auto方法
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.WriteLine("结束了"); //这句要改
Console.ReadLine();
}
public static void Auto(object i)//多线程执行的方法
{
if (string.Equals(i, 2))
{
Thread.Sleep(2000);
}
Console.WriteLine(i.ToString());
}
结束了 这三个字不一定 真正在 最后一行输出。
因为这时是 主线程+子线程 这些线程的执行顺序不确定,可能主线程老早就执行了。
也就说可能结束了 这三个字很早就会输出。
3、主题 保证 结束了 在最后输出。
方法1:
//这是主线程,一直都会执行。
目前一直在进行的是 一个主线程+多个子线程
while (true)
{
Thread.Sleep(1000);//这句写着,主要是没必要循环那么多次。
去掉也可以。
int maxWorkerThreads, workerThreads;
int portThreads;
ThreadPool.GetMaxThreads(out maxWorkerThreads, out portThreads);
ThreadPool.GetAvailableThreads(out workerThreads, out portThreads);
if (maxWorkerThreads - workerThreads == 0)
{
Console.WriteLine("结束了");
break;
}
}
GetAvailableThreads():检索由 GetMaxThreads 返回的线程池线程的最大数目和当前活动数目之间的差值。
而GetMaxThreads 检索可以同时处于活动状态的线程池请求的数目。
通过最大数目减可用数目就可以得到当前活动线程的数目,如果为零,那就说明没有活动线程,说明所有线程运行完毕。
方法2 : Monitor
见下篇文章:/handboy/blog/item/681d093875d6e6cdd56225ae.html
class Program
{
static object locker = new object();
static int runningThreads = 0;
static void Main(string[] args)
{
try
{
ThreadPool.SetMaxThreads(4, 4); //设置最大线程数 using System.Threading;
runningThreads = 10;
for (int i = 0; i < runningThreads; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(Auto), i);//线程池指定线程执行Auto方法
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
lock (locker)
{
while (runningThreads > 0)
{
Monitor.Wait(locker);
}
}
Console.WriteLine("结束了");
Console.ReadLine();
}
public static void Auto(object i)//多线程执行的方法
{
if (string.Equals(i, 2))
{
Thread.Sleep(2000);
}
lock (locker)
{
runningThreads--;
Monitor.Pulse(locker);
}
Console.WriteLine(i.ToString());
}
}
方法3:WaitHandle (推荐用这个方法)
。
/ganggang0217/blog/item/fe2a004ecad3acdcd0c86a67.html
public void testThreads()
{
ManualResetEvent[] _ManualEvents = new ManualResetEvent[10];
for (int i = 0; i < 10; i++)
{
_ManualEvents[i] = new ManualResetEvent(false);
System.Threading.ThreadPool.QueueUserWorkItem(new WaitCallback(testMethod), _ManualEvents[i]);
}
WaitHandle.WaitAll(_ManualEvents);
// 线程结束后执行后面的主线程代码
Console.WriteLine("结束了");
Console.ReadLine();
}
public void testMethod(object objEvent)
{
//TODO: Add your code here
ManualResetEvent e = (ManualResetEvent)objEvent;
e.Set();
}为什么在Ubuntu上用c开线程后不执行回调函数
可以通过线程池ThreadPool来解决,使用ThreadPool.QueueUserWorkItem(回调函数,object),将参数封装在一个类的对象中,传给回调函数去执行。
TheadPool的用法:
1、创建一个ManualResetEvent的对象,就像一个信号灯,指示线程的挂起和执行;
2、ManualResetEvent对象创建时,可以指定默认状态:true为有信号,false为无信号;
3、调用Reset()方法重置状态;
4、调用WaitOne()方法,使线程处于等待状态;
5、调用Set()方法设置状态。
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Collections;
namespace Demo
{
public class ParamObject
{
public int number;
public ParamObject (int number)
{
this.number = number;
}
}
public class ThreadClass
{
public Hashtable aHashTable;
public ManualResetEvent aManualResetEvent;
public static int iCount = 0;
public static int iMaxCount = 0;
public ThreadClass(int maxCount)
{
aHashTable = new Hashtable(maxCount);
iMaxCount = maxCount;
}
public void ThreadRun(object aParamObject)
{
Console.WriteLine("HashCode: {0}, Number in Object: {1}", Thread.CurrentThread.GetHashCode(), ((ParamObject)aParamObject).number);
lock (aHashTable)
{
if (!aHashTable.ContainsKey(Thread.CurrentThread.GetHashCode()))
{
aHashTable.Add(Thread.CurrentThread.GetHashCode(), 0);
}
aHashTable[Thread.CurrentThread.GetHashCode()] = (int)aHashTable[Thread.CurrentThread.GetHashCode()] + 1;
}
Thread.Sleep(3000);
Interlocked.Increment(ref iCount);
if (iCount == iMaxCount)
{
Console.WriteLine("Setting aManualResetEvent...");
aManualResetEvent.Set();
}
}
}
class Program
{
public static void Main(string[] args)
{
bool enableThreadPool = false;
int iMaxCount = 20;
ManualResetEvent aManualResetEvent = new ManualResetEvent(false);
Console.WriteLine("Insert {0} items to Thread Pool.", iMaxCount);
ThreadClass aThreadClass = new ThreadClass(iMaxCount);
aThreadClass.aManualResetEvent = aManualResetEvent;
// First, add an item to check if your system supports ThreadPool API function or not.
try
{
ThreadPool.QueueUserWorkItem(new WaitCallback(aThreadClass.ThreadRun), new ParamObject(0));
enableThreadPool = true;
}
catch (NotSupportedException ex)
{
Console.WriteLine("Thread Pool API is not supported in this system.");
enableThreadPool = false;
}
if (enableThreadPool)
{
for (int i = 1; i < iMaxCount; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(aThreadClass.ThreadRun), new ParamObject(i));
}
Console.WriteLine("Waiting for thread pool to drain");
aManualResetEvent.WaitOne(Timeout.Infinite, true);
Console.WriteLine("Thread Pool has been drained.");
Console.WriteLine("Load threads info:");
foreach (object key in aThreadClass.aHashTable.Keys)
{
Console.WriteLine("Key: {0}, Value: {1}", key, aThreadClass.aHashTable[key]);
}
}
Console.ReadLine();
}
}
}
diyvm怎么样?diyvm是一家国内成立时间比较久的主机商家了,大约在6年前站长曾经用过他家的美国机房的套餐,非常稳定,适合做站,目前商家正在针对香港沙田机房的VPS进行促销,给的是五折优惠,续费同价,香港沙田机房走的是CN2直连的线路,到大陆地区的速度非常好,DiyVM商家采用小带宽不限流量的形式,带宽2Mbps起步,做站完全够用,有需要的朋友可以入手。diyvm优惠码:五折优惠码:OFF50...
官方网站:https://www.akkocloud.com/AkkoCloud新品英国伦敦CN2 GIA已上线三网回程CN2 GIA 国内速度优秀.电信去程CN2 GIALooking Glass:http://lonlg.akkocloud.com/Speedtest:http://lonlg.akkocloud.com/speedtest/新品上线刚好碰上国庆节 特此放上国庆专属九折循环优惠...
IncogNet LLC是个由3个人运作的美国公司,主要特色是隐私保护,号称绝对保护用户的隐私安全。业务涵盖虚拟主机、VPS等,支持多种数字加密货币、PayPal付款。注册账号也很简单,输入一个姓名、一个邮箱、国家随便选,填写一个邮箱就搞定了,基本上不管资料的真假。当前促销的vps位于芬兰机房,全部都是AMD Ryzen系列的CPU,性能不会差的!5折优惠码:CRYPTOMONTH,支持:BTC,...
queueuserworkitem为你推荐
bbsxpdvbbs bbsxp LeadBBS 对比天天酷跑刷积分教程天天酷跑积分怎么刷最快?工信部备案去国家工信部备案需要什么手续呢安卓应用平台手机系统应用在哪童之磊华硕的四核平板电脑,怎么样?蘑菇街美丽说蘑菇街、美丽说这类网站前期是怎么推广的?直播加速请问哪种播放器的可以播放加速,并且可以保存ios7固件下载ios7发布当天是否有固件下载网站地图制作怎么制作网站地图啊,网站地图制作如何制作、提交网站地图
域名抢注工具 site5 hawkhost 香港主机 gomezpeer 私有云存储 国外网站代理服务器 150邮箱 数字域名 hostker 可外链网盘 空间技术网 web服务器安全 银盘服务是什么 域名与空间 免费的域名 云服务器比较 测速电信 netvigator zencart安装 更多