简单泛型类,实现线程并发

本类主要是用于解决一些非常简单的线性过程的并发问题:
比如做一个循环,每次都是出入参数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();
        }
    }
}

在使用的过程中我发现了一些问题,我需要对一个市区所有公安的辖区进行评估。
比如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;
                }
            }
        }

代码写的比较恶心,但是功能实现了

posted on 2008-07-13 14:21  Herist  阅读(526)  评论(0编辑  收藏  举报

导航