简单泛型类,实现线程并发
本类主要是用于解决一些非常简单的线性过程的并发问题:
比如做一个循环,每次都是出入参数P,返回T。
每次都执行同样的过程,但是该过程消耗的时间又比较长,所以想到用多线程解决该问题,正好泛型可以解决参数和返回类型不确定的问题,在调用完毕之后,返回一个返回类型的数组。
附件:简单线程并发的demo
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace ConcurrentManager
{
/// <summary>
/// 并行处理回调委托
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="tList"></param>
public delegate void ConcurrentCallBackHandler<T>(List<T> tList);
/// <summary>
/// 处理事件委托
/// </summary>
/// <typeparam name="P"></typeparam>
/// <typeparam name="T"></typeparam>
/// <param name="para"></param>
/// <returns></returns>
public delegate T ConcurrentExecHandler<P,T>(P para);
/// <summary>
/// 并发处理泛型类,T为泛型的参数类型
/// </summary>
public class ConcurrentManager<P,T>
{
public event ConcurrentCallBackHandler<T> CallBackEvent;
private ConcurrentExecHandler<P, T> executeOneHandler = null;
/// <summary>
/// 参数处理方法委托
/// P 参数类型,T为返回类型
/// </summary>
public ConcurrentExecHandler<P, T> ExecuteOneEvent
{
set
{
if (executeOneHandler == null)
executeOneHandler = value;
}
}
List<T> resultList = new List<T>();
/// <summary>
/// 或者的线程的数目
/// </summary>
int ATCount=0;
object lockFlag = new object();
public void MultiExec(P[] parameters)
{
ATCount = parameters.Length;
foreach (P msg in parameters)
{
Thread thread = new Thread(new ParameterizedThreadStart(HandleOne));
thread.Start(msg);
}
}
/// <summary>
/// 用来并行函数
/// </summary>
/// <param name="msg"></param>
private void HandleOne(object msg)
{
T t = executeOneHandler((P)msg);
//处理语句
lock (lockFlag)
{
resultList.Add(t);
ATCount--;
}
if (ATCount == 0)
{
if (CallBackEvent != null)
CallBackEvent(resultList);
}
Thread.CurrentThread.Abort();
}
}
}
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace ConcurrentManager
{
/// <summary>
/// 并行处理回调委托
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="tList"></param>
public delegate void ConcurrentCallBackHandler<T>(List<T> tList);
/// <summary>
/// 处理事件委托
/// </summary>
/// <typeparam name="P"></typeparam>
/// <typeparam name="T"></typeparam>
/// <param name="para"></param>
/// <returns></returns>
public delegate T ConcurrentExecHandler<P,T>(P para);
/// <summary>
/// 并发处理泛型类,T为泛型的参数类型
/// </summary>
public class ConcurrentManager<P,T>
{
public event ConcurrentCallBackHandler<T> CallBackEvent;
private ConcurrentExecHandler<P, T> executeOneHandler = null;
/// <summary>
/// 参数处理方法委托
/// P 参数类型,T为返回类型
/// </summary>
public ConcurrentExecHandler<P, T> ExecuteOneEvent
{
set
{
if (executeOneHandler == null)
executeOneHandler = value;
}
}
List<T> resultList = new List<T>();
/// <summary>
/// 或者的线程的数目
/// </summary>
int ATCount=0;
object lockFlag = new object();
public void MultiExec(P[] parameters)
{
ATCount = parameters.Length;
foreach (P msg in parameters)
{
Thread thread = new Thread(new ParameterizedThreadStart(HandleOne));
thread.Start(msg);
}
}
/// <summary>
/// 用来并行函数
/// </summary>
/// <param name="msg"></param>
private void HandleOne(object msg)
{
T t = executeOneHandler((P)msg);
//处理语句
lock (lockFlag)
{
resultList.Add(t);
ATCount--;
}
if (ATCount == 0)
{
if (CallBackEvent != null)
CallBackEvent(resultList);
}
Thread.CurrentThread.Abort();
}
}
}
在使用的过程中我发现了一些问题,我需要对一个市区所有公安的辖区进行评估。
比如W市下有 A、B、C三个区,现每个区里面发生的案件进行评估(一系列的查询与分析,在此不叙述)
评估的结果返回,然后在地图上针对这个区的评估结果 以不同的颜色显示出来。
原来的线性查询显然比较慢,我开始使用上面的类,进行了一个多线程处理,虽然速度上有了改善,但是新的问题出现了
我新建了 a、b、c三个线程,去负责三个区的评估,然后当耗时最长的那个区的线程执行完毕后,触发了CallBackEvent,
假设 c最后结束,则线程c触发CallBackEvent,也就等于c调用了所有的delegate[],如果遇到winForm的控件的话,可能会有
CrossThread(线程交错)的异常。
所以,我希望在a、b、c运行结束以后,程序的执行能够回到主线程中,所以我判断ATCount==0的回调过程就不能放在 HandleOne方法中,
我把这个过程移到了 主线程调用的 MultiExec方法,代码如下:
public void MultiExec(P[] parameters)
{
ATCount = parameters.Length;
for (int i = 0; i < parameters.Length; i++ )
{
Thread thread = new Thread(new ParameterizedThreadStart(HandleOne));
thread.Start(parameters[i]);
}
//预先判断,防止线程执行速度过快
if (ATCount == 0 && CallBackEvent != null)
{
CallBackEvent(resultList);
return;
}
//循环监听
while (ATCount != 0)
{
Thread.Sleep(10);
if (ATCount == 0 && CallBackEvent != null)
{
CallBackEvent(resultList);
break;
}
}
}
{
ATCount = parameters.Length;
for (int i = 0; i < parameters.Length; i++ )
{
Thread thread = new Thread(new ParameterizedThreadStart(HandleOne));
thread.Start(parameters[i]);
}
//预先判断,防止线程执行速度过快
if (ATCount == 0 && CallBackEvent != null)
{
CallBackEvent(resultList);
return;
}
//循环监听
while (ATCount != 0)
{
Thread.Sleep(10);
if (ATCount == 0 && CallBackEvent != null)
{
CallBackEvent(resultList);
break;
}
}
}
代码写的比较恶心,但是功能实现了