【edobnet】利用.Net 執行緒池提高應用程式效能.

iDotNetSpace發表於2008-06-16
通常在大資料量計算的應用程式裡,CPU大部分時間處理等待狀態.在一個單執行緒的應用程式裡,這些查詢會導致window訊息處理能力阻塞,這裡會導致計算時間很長,CPU利用率也非常低.
           最近一直在研究,提高處理效能的方法.
            開始利用,多執行緒,非同步的方法來實現,
            下面的語句是用來分段進行資料整合, (如按天,或按月,對中間資料進行整合)整合SQL通過批量生成
            在單執行緒的執行時間,CPU利用率一般在1-10%,(伺服器HP 580 4 CPU XEON 3.0G 16G記憶體,加盤櫃),這樣整合時間太長。
          如果分段整合,CPU利用率就在40-80%得到比較大的利用。
【edobnet】利用.Net 執行緒池提高應用程式效能.    FileInfo[] files;
【edobnet】利用.Net 執行緒池提高應用程式效能.        
private void button1_Click(object sender, System.EventArgs e)
【edobnet】利用.Net 執行緒池提高應用程式效能.        
{
【edobnet】利用.Net 執行緒池提高應用程式效能.            
if(folderBrowserDialog1.ShowDialog() == DialogResult.OK)
【edobnet】利用.Net 執行緒池提高應用程式效能.            
{
【edobnet】利用.Net 執行緒池提高應用程式效能.                System.IO.DirectoryInfo di 
= new DirectoryInfo(folderBrowserDialog1.SelectedPath);
【edobnet】利用.Net 執行緒池提高應用程式效能.                files 
= di.GetFiles();
【edobnet】利用.Net 執行緒池提高應用程式效能.            
【edobnet】利用.Net 執行緒池提高應用程式效能.                
【edobnet】利用.Net 執行緒池提高應用程式效能.                ThreadStart ts 
= new ThreadStart(start);
【edobnet】利用.Net 執行緒池提高應用程式效能.                Thread thread 
= new Thread(ts);
【edobnet】利用.Net 執行緒池提高應用程式效能.                thread.Start();
【edobnet】利用.Net 執行緒池提高應用程式效能.                
【edobnet】利用.Net 執行緒池提高應用程式效能.                
【edobnet】利用.Net 執行緒池提高應用程式效能.            }

【edobnet】利用.Net 執行緒池提高應用程式效能.        }

【edobnet】利用.Net 執行緒池提高應用程式效能.        
public  delegate string myMethodDelegate( object[] args);
【edobnet】利用.Net 執行緒池提高應用程式效能.        
static int t = 0;
【edobnet】利用.Net 執行緒池提高應用程式效能.        
void start()
【edobnet】利用.Net 執行緒池提高應用程式效能.        
{
【edobnet】利用.Net 執行緒池提高應用程式效能.            
foreach(FileInfo file in files)
【edobnet】利用.Net 執行緒池提高應用程式效能.            
{
【edobnet】利用.Net 執行緒池提高應用程式效能.                System.IO.StreamReader sr 
= new StreamReader(file.FullName,System.Text.Encoding.Default);
【edobnet】利用.Net 執行緒池提高應用程式效能.                
string txt = sr.ReadToEnd();
【edobnet】利用.Net 執行緒池提高應用程式效能.                sr.Close();
【edobnet】利用.Net 執行緒池提高應用程式效能.                myMethodDelegate ddd
= new myMethodDelegate(Work2);
【edobnet】利用.Net 執行緒池提高應用程式效能.                ddd.BeginInvoke(
new object[]{txt_connectString.Text,txt,file.FullName},new AsyncCallback(EndWorkBack), null);
【edobnet】利用.Net 執行緒池提高應用程式效能.
【edobnet】利用.Net 執行緒池提高應用程式效能.                Write(
string.Format("T:{0}|{1}   {1}\r\n",DateTime.Now,file.FullName,t));
【edobnet】利用.Net 執行緒池提高應用程式效能.        
【edobnet】利用.Net 執行緒池提高應用程式效能.                
//_Task.StartTask(new TaskDelegate(_Task.Work2),new object[]{txt_connectString.Text,txt});
【edobnet】利用.Net 執行緒池提高應用程式效能.
                
【edobnet】利用.Net 執行緒池提高應用程式效能.            }

【edobnet】利用.Net 執行緒池提高應用程式效能.            
【edobnet】利用.Net 執行緒池提高應用程式效能.        }

【edobnet】利用.Net 執行緒池提高應用程式效能.        
public string Work2( object[] args)
【edobnet】利用.Net 執行緒池提高應用程式效能.        
{
【edobnet】利用.Net 執行緒池提高應用程式效能.            
using(SqlConnection conn = new SqlConnection(args[0].ToString()))
【edobnet】利用.Net 執行緒池提高應用程式效能.            
{
【edobnet】利用.Net 執行緒池提高應用程式效能.                
using(SqlCommand comm = new SqlCommand(args[1].ToString(),conn))
【edobnet】利用.Net 執行緒池提高應用程式效能.                
{
【edobnet】利用.Net 執行緒池提高應用程式效能.                    comm.CommandTimeout 
= 60000;
【edobnet】利用.Net 執行緒池提高應用程式效能.                    conn.Open();
【edobnet】利用.Net 執行緒池提高應用程式效能.                    comm.ExecuteNonQuery();
【edobnet】利用.Net 執行緒池提高應用程式效能.                }

【edobnet】利用.Net 執行緒池提高應用程式效能.                conn.Close();
【edobnet】利用.Net 執行緒池提高應用程式效能.            }

【edobnet】利用.Net 執行緒池提高應用程式效能.            
return args[2].ToString();
【edobnet】利用.Net 執行緒池提高應用程式效能.
【edobnet】利用.Net 執行緒池提高應用程式效能.            
【edobnet】利用.Net 執行緒池提高應用程式效能.        }

【edobnet】利用.Net 執行緒池提高應用程式效能.        
int i =0;
【edobnet】利用.Net 執行緒池提高應用程式效能.        
protected void EndWorkBack( IAsyncResult ar ) 
【edobnet】利用.Net 執行緒池提高應用程式效能.        

【edobnet】利用.Net 執行緒池提高應用程式效能.            myMethodDelegate ddd 
= (myMethodDelegate)ar.AsyncState; 
【edobnet】利用.Net 執行緒池提高應用程式效能.            
string result = ddd.EndInvoke( ar ); 
【edobnet】利用.Net 執行緒池提高應用程式效能.            i
++;
【edobnet】利用.Net 執行緒池提高應用程式效能.            Write(
string.Format("T:{3}:{2}:{0}    {1}\r\n",result,DateTime.Now,i,t));
【edobnet】利用.Net 執行緒池提高應用程式效能.        }
 
【edobnet】利用.Net 執行緒池提高應用程式效能.        
public void Write(string msg)
【edobnet】利用.Net 執行緒池提高應用程式效能.        
{
【edobnet】利用.Net 執行緒池提高應用程式效能.            System.IO.StreamWriter sw 
= new StreamWriter("C:\\install.log",true,System.Text.Encoding.Default);
【edobnet】利用.Net 執行緒池提高應用程式效能.            sw.WriteLine(msg);
【edobnet】利用.Net 執行緒池提高應用程式效能.            sw.Close();
【edobnet】利用.Net 執行緒池提高應用程式效能.
【edobnet】利用.Net 執行緒池提高應用程式效能.        }

         不過上面程式也有一點問題,就是非同步執行緒資料沒有好的控制。如果同時執行執行緒,過多,CPU時間片分配就不合理,執行速度反而慢。
    後來就一直想用執行緒池的來合理處理執行緒。
         。Net自帶的執行緒池使用起來比較簡單。
       通過System.Threading.ThreadTool類就可以使用,
    定義回撥方法
            WaitCallback async = new WaitCallback(FExeute);
        通過ThreadPool.QueueUserWorkItem(async,service);加入佇列
        回撥方法執行運算
        

【edobnet】利用.Net 執行緒池提高應用程式效能.public  void FExeute(object Param)
【edobnet】利用.Net 執行緒池提高應用程式效能.        
{
【edobnet】利用.Net 執行緒池提高應用程式效能.            
//myResetEvent.WaitOne();
【edobnet】利用.Net 執行緒池提高應用程式效能.
            using(TG_EvaluteBaseDatasSet service = (TG_EvaluteBaseDatasSet)Param)
【edobnet】利用.Net 執行緒池提高應用程式效能.                  
{
【edobnet】利用.Net 執行緒池提高應用程式效能.                service.doResult();
【edobnet】利用.Net 執行緒池提高應用程式效能.                writeFile(Path,service)    ;
【edobnet】利用.Net 執行緒池提高應用程式效能.                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)));
【edobnet】利用.Net 執行緒池提高應用程式效能.            }

【edobnet】利用.Net 執行緒池提高應用程式效能.            Interlocked.Decrement(
ref number);
【edobnet】利用.Net 執行緒池提高應用程式效能.            
//number--;
【edobnet】利用.Net 執行緒池提高應用程式效能.
            
【edobnet】利用.Net 執行緒池提高應用程式效能.        }

    其中Interlocked.Decrement,是呼叫原子操作,進行減操作,
            Interlocked.Increment(ref number);是呼叫原子操作,進行加
    原子操作在多執行緒中不會有衝突。
          執行緒池有幾點好處,
        1。多執行緒執行,
        2。根據CPU個數,效能等,合理安排執行的執行緒,(在實際操作過程中,通過SQL SERVER企業管理器中檢視當前活動的程式數,可以看到當前正在執行的執行緒數)
        3。非同步操作。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-349323/,如需轉載,請註明出處,否則將追究法律責任。

相關文章