c#等待所有子线程执行完毕方法
2015-07-09 08:51
274 查看
当我们在使用线程中,你会发现主线结束后子线程的结果才显示出来。现在我要等待所以子线程结束,然后在显示结果,怎么做呢?
方法如下:
1、使用 ManualResetEvent,代码如下:
using System.Threading;
namespace ThreadStudy
{
/// <summary>
/// 等待所有子线程结束
/// </summary>
class StopAllWaitBySubThread
{
List<ManualResetEvent> manualEvents = new List<ManualResetEvent>();
public void Main()
{
for (int i = 0; i < 5; i++)
{
ManualResetEvent mre = new ManualResetEvent(false);
manualEvents.Add(mre);
ThreadPool.QueueUserWorkItem(ThreadMethod, mre);
}
WaitHandle.WaitAll(manualEvents.ToArray());
Console.WriteLine("Thread Finished!");
}
private void ThreadMethod(object obj)
{
//等待2秒,用于模拟系统在处理事情
Thread.Sleep(2000);
ManualResetEvent mre = (ManualResetEvent)obj;
mre.Set();
Console.WriteLine("Thread execute");
}
}
}
此种方法线程中只传递了信号,那要传递参数怎么办?可以采用类,将信号放在类中来解决,代码如下。
using System.Threading;
namespace ThreadStudy
{
/// <summary>
/// 等待所有子线程结束
/// </summary>
class StopAllWaitBySubThread
{
List<ManualResetEvent> manualEvents = new List<ManualResetEvent>();
public void Main()
{
for (int i = 0; i < 5; i++)
{
ManualResetEvent mre = new ManualResetEvent(false);
manualEvents.Add(mre);
Param pra = new Param();
pra.mrEvent = mre;
pra.praData = i;
ThreadPool.QueueUserWorkItem(ThreadMethod, pra);
}
WaitHandle.WaitAll(manualEvents.ToArray());
Console.WriteLine("Thread Finished!");
}
private void ThreadMethod(object obj)
{
Thread.Sleep(2000);
Param pra = (Param)obj;
pra.mrEvent.Set();
Console.WriteLine("Thread execute at {0}", pra.praData);
}
}
public class Param
{
public ManualResetEvent mrEvent;
public int praData;
}
}
2、判断线程数
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ThreadStudy
{
/// <summary>
/// 判断当所有子线程执行完毕
/// </summary>
class ThreadPoolStop
{
public void Main()
{
for (int i = 0; i < 5; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadMethod), i);
}
int maxWorkerThreads, workerThreads;
int portThreads;
while (true)
{
/*
GetAvailableThreads():检索由 GetMaxThreads 返回的线程池线程的最大数目和当前活动数目之间的差值。
而GetMaxThreads 检索可以同时处于活动状态的线程池请求的数目。
通过最大数目减可用数目就可以得到当前活动线程的数目,如果为零,那就说明没有活动线程,说明所有线程运行完毕。
*/
ThreadPool.GetMaxThreads(out maxWorkerThreads, out portThreads);
ThreadPool.GetAvailableThreads(out workerThreads, out portThreads);
if (maxWorkerThreads - workerThreads == 0)
{
Console.WriteLine("Thread Finished!");
break;
}
}
}
private void ThreadMethod(object i)
{
//模拟程序运行
Thread.Sleep((new Random().Next(1, 4)) * 1000);
Console.WriteLine("Thread execute at {0}", i.ToString());
}
}
}
3、使用Monitor
using System.Threading;
namespace ThreadStudy
{
class StopAllSubThread
{
int _ThreadCount = 5;
int finishcount = 0;
object locker = new object();
public void Main()
{
for (int i = 0; i < _ThreadCount; i++)
{
Thread trd = new Thread(new ParameterizedThreadStart(ThreadMethod));
trd.Start(i);
}
lock (locker)
{
while (finishcount != _ThreadCount)
{
Monitor.Wait(locker);//等待
}
}
Console.WriteLine("Thread Finished!");
}
private void ThreadMethod(object obj)
{
//模拟执行程序
Thread.Sleep(3000);
Console.WriteLine("Thread execute at {0}", obj.ToString());
lock (locker)
{
finishcount++;
Monitor.Pulse(locker); //完成,通知等待队列,告知已完,执行下一个。
}
}
}
}
方法如下:
1、使用 ManualResetEvent,代码如下:
using System.Threading;
namespace ThreadStudy
{
/// <summary>
/// 等待所有子线程结束
/// </summary>
class StopAllWaitBySubThread
{
List<ManualResetEvent> manualEvents = new List<ManualResetEvent>();
public void Main()
{
for (int i = 0; i < 5; i++)
{
ManualResetEvent mre = new ManualResetEvent(false);
manualEvents.Add(mre);
ThreadPool.QueueUserWorkItem(ThreadMethod, mre);
}
WaitHandle.WaitAll(manualEvents.ToArray());
Console.WriteLine("Thread Finished!");
}
private void ThreadMethod(object obj)
{
//等待2秒,用于模拟系统在处理事情
Thread.Sleep(2000);
ManualResetEvent mre = (ManualResetEvent)obj;
mre.Set();
Console.WriteLine("Thread execute");
}
}
}
此种方法线程中只传递了信号,那要传递参数怎么办?可以采用类,将信号放在类中来解决,代码如下。
using System.Threading;
namespace ThreadStudy
{
/// <summary>
/// 等待所有子线程结束
/// </summary>
class StopAllWaitBySubThread
{
List<ManualResetEvent> manualEvents = new List<ManualResetEvent>();
public void Main()
{
for (int i = 0; i < 5; i++)
{
ManualResetEvent mre = new ManualResetEvent(false);
manualEvents.Add(mre);
Param pra = new Param();
pra.mrEvent = mre;
pra.praData = i;
ThreadPool.QueueUserWorkItem(ThreadMethod, pra);
}
WaitHandle.WaitAll(manualEvents.ToArray());
Console.WriteLine("Thread Finished!");
}
private void ThreadMethod(object obj)
{
Thread.Sleep(2000);
Param pra = (Param)obj;
pra.mrEvent.Set();
Console.WriteLine("Thread execute at {0}", pra.praData);
}
}
public class Param
{
public ManualResetEvent mrEvent;
public int praData;
}
}
2、判断线程数
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ThreadStudy
{
/// <summary>
/// 判断当所有子线程执行完毕
/// </summary>
class ThreadPoolStop
{
public void Main()
{
for (int i = 0; i < 5; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadMethod), i);
}
int maxWorkerThreads, workerThreads;
int portThreads;
while (true)
{
/*
GetAvailableThreads():检索由 GetMaxThreads 返回的线程池线程的最大数目和当前活动数目之间的差值。
而GetMaxThreads 检索可以同时处于活动状态的线程池请求的数目。
通过最大数目减可用数目就可以得到当前活动线程的数目,如果为零,那就说明没有活动线程,说明所有线程运行完毕。
*/
ThreadPool.GetMaxThreads(out maxWorkerThreads, out portThreads);
ThreadPool.GetAvailableThreads(out workerThreads, out portThreads);
if (maxWorkerThreads - workerThreads == 0)
{
Console.WriteLine("Thread Finished!");
break;
}
}
}
private void ThreadMethod(object i)
{
//模拟程序运行
Thread.Sleep((new Random().Next(1, 4)) * 1000);
Console.WriteLine("Thread execute at {0}", i.ToString());
}
}
}
3、使用Monitor
using System.Threading;
namespace ThreadStudy
{
class StopAllSubThread
{
int _ThreadCount = 5;
int finishcount = 0;
object locker = new object();
public void Main()
{
for (int i = 0; i < _ThreadCount; i++)
{
Thread trd = new Thread(new ParameterizedThreadStart(ThreadMethod));
trd.Start(i);
}
lock (locker)
{
while (finishcount != _ThreadCount)
{
Monitor.Wait(locker);//等待
}
}
Console.WriteLine("Thread Finished!");
}
private void ThreadMethod(object obj)
{
//模拟执行程序
Thread.Sleep(3000);
Console.WriteLine("Thread execute at {0}", obj.ToString());
lock (locker)
{
finishcount++;
Monitor.Pulse(locker); //完成,通知等待队列,告知已完,执行下一个。
}
}
}
}
相关文章推荐
- C# 多线程(lock,Monitor,Mutex,同步事件和等待句柄)
- C#中的线程(一)入门
- C#webBrowser使用代理服务器的方法winform
- C#操作剪切板内容
- c# webconfig配置修改
- 用C#来查看电脑硬件和系统信息
- C# 课堂总结4-类(常用的类)
- Csharp学习第三天
- C#利用最新版的WPS实现导入导出
- C# COM组件操作Excel
- C# COM组件操作Excel
- C#接口的理解
- C#运算符的优先级
- [2]项目创建-使用C#.NET开发基于本地数据缓存的PC客户端
- 初次接触C#
- C#定时器
- [1]开发准备-使用C#.NET开发基于本地数据缓存的PC客户端
- c#定时器和global实现自动job示例
- c#第五次作业
- C#操作Excel