利用.Net 线程池提高应用程序性能.

  
            通常在大数据量计算的应用程序里,CPU大部分时间处理等待状态.在一个单线程的应用程序里,这些查询会导致window消息处理能力阻塞,这里会导致计算时间很长,CPU利用率也非常低.
           最近一直在研究,提高处理性能的方法.
            开始利用,多线程,异步的方法来实现,
            下面的语句是用来分段进行数据整合, (如按天,或按月,对中间数据进行整合)整合SQL通过批量生成
            在单线程的执行时间,CPU利用率一般在1-10%,(服务器HP 580 4 CPU XEON 3.0G 16G内存,加盘柜),这样整合时间太长。
          如果分段整合,CPU利用率就在40-80%得到比较大的利用。

None.gif     FileInfo[] files;
None.gif        
private   void  button1_Click( object  sender, System.EventArgs e)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
if(folderBrowserDialog1.ShowDialog() == DialogResult.OK)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                System.IO.DirectoryInfo di 
= new DirectoryInfo(folderBrowserDialog1.SelectedPath);
InBlock.gif                files 
= di.GetFiles();
InBlock.gif            
InBlock.gif                
InBlock.gif                ThreadStart ts 
= new ThreadStart(start);
InBlock.gif                Thread thread 
= new Thread(ts);
InBlock.gif                thread.Start();
InBlock.gif                
InBlock.gif                
ExpandedSubBlockEnd.gif            }

ExpandedBlockEnd.gif        }

None.gif        
public    delegate   string  myMethodDelegate(  object [] args);
None.gif        
static   int  t  =   0 ;
None.gif        
void  start()
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
foreach(FileInfo file in files)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                System.IO.StreamReader sr 
= new StreamReader(file.FullName,System.Text.Encoding.Default);
InBlock.gif                
string txt = sr.ReadToEnd();
InBlock.gif                sr.Close();
InBlock.gif                myMethodDelegate ddd
= new myMethodDelegate(Work2);
ExpandedSubBlockStart.gifContractedSubBlock.gif                ddd.BeginInvoke(
new object[]dot.gif{txt_connectString.Text,txt,file.FullName},new AsyncCallback(EndWorkBack), null);
InBlock.gif
InBlock.gif                Write(
string.Format("T:{0}|{1}   {1}\r\n",DateTime.Now,file.FullName,t));
InBlock.gif        
InBlock.gif                
//_Task.StartTask(new TaskDelegate(_Task.Work2),new object[]{txt_connectString.Text,txt});
InBlock.gif
                
ExpandedSubBlockEnd.gif            }

InBlock.gif            
ExpandedBlockEnd.gif        }

None.gif        
public   string  Work2(  object [] args)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
using(SqlConnection conn = new SqlConnection(args[0].ToString()))
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
using(SqlCommand comm = new SqlCommand(args[1].ToString(),conn))
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    comm.CommandTimeout 
= 60000;
InBlock.gif                    conn.Open();
InBlock.gif                    comm.ExecuteNonQuery();
ExpandedSubBlockEnd.gif                }

InBlock.gif                conn.Close();
ExpandedSubBlockEnd.gif            }

InBlock.gif            
return args[2].ToString();
InBlock.gif
InBlock.gif            
ExpandedBlockEnd.gif        }

None.gif        
int  i  = 0 ;
None.gif        
protected   void  EndWorkBack( IAsyncResult ar ) 
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif
InBlock.gif            myMethodDelegate ddd 
= (myMethodDelegate)ar.AsyncState; 
InBlock.gif            
string result = ddd.EndInvoke( ar ); 
InBlock.gif            i
++;
InBlock.gif            Write(
string.Format("T:{3}:{2}:{0}    {1}\r\n",result,DateTime.Now,i,t));
ExpandedBlockEnd.gif        }
 
None.gif        
public   void  Write( string  msg)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            System.IO.StreamWriter sw 
= new StreamWriter("C:\\install.log",true,System.Text.Encoding.Default);
InBlock.gif            sw.WriteLine(msg);
InBlock.gif            sw.Close();
InBlock.gif
ExpandedBlockEnd.gif        }

         不过上面程序也有一点问题,就是异步线程数据没有好的控制。如果同时执行线程,过多,CPU时间片分配就不合理,执行速度反而慢。
    后来就一直想用线程池的来合理处理线程。
         。Net自带的线程池使用起来比较简单。
       通过System.Threading.ThreadTool类就可以使用,
    定义回调方法
            WaitCallback async = new WaitCallback(FExeute);
        通过ThreadPool.QueueUserWorkItem(async,service);加入队列
        回调方法执行运算
        

None.gif public    void  FExeute( object  Param)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
//myResetEvent.WaitOne();
InBlock.gif
            using(TG_EvaluteBaseDatasSet service = (TG_EvaluteBaseDatasSet)Param)
ExpandedSubBlockStart.gifContractedSubBlock.gif                  
dot.gif{
InBlock.gif                service.doResult();
InBlock.gif                writeFile(Path,service)    ;
InBlock.gif                OnTgReport(
new ReportEvent(service.TE_PASS_RANGE,service.TE_YEAR,service.TE_MONTH,int.Parse(service.TE_I_E_FLAG),int.Parse(service.TE_ENTRY_TYPE)));
ExpandedSubBlockEnd.gif            }

InBlock.gif            Interlocked.Decrement(
ref number);
InBlock.gif            
//number--;
InBlock.gif
            
ExpandedBlockEnd.gif        }

    其中Interlocked.Decrement,是调用原子操作,进行减操作,
            Interlocked.Increment(ref number);是调用原子操作,进行加
    原子操作在多线程中不会有冲突。
          线程池有几点好处,
        1。多线程执行,
        2。根据CPU个数,性能等,合理安排执行的线程,(在实际操作过程中,通过SQL SERVER企业管理器中查看当前活动的进程数,可以看到当前正在执行的线程数)
        3。异步操作。
       相关资源:
       http://www.ddvip.net/program/c-/index2/15.htm
        http://www.codeproject.com/csharp/threadtests.asp
        http://www.microsoft.com/china/MSDN/library/netFramework/netframework/NECLRT.mspx

    源码下载:
            http://files.cnblogs.com/edobnet/Report.rar
           

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值