首先無論是那個BeginInvoke()都是異步執行子線程函數,有些同學疑問了,異步執行是不是在子線程的函數沒有執行完,
下一次執行又開辟了新的線程進行執行呢(微軟官方給出的BeginInvoke並不是多線程執行的異步)我的測試卻讓我對此感覺迷
惑--下面的代碼我會講到測試代碼
(不同A)----線程的宿主不同--此處和this.Invoke()與Delegate.Invoke一樣(可參考MSDN http://msdn.microsoft.com/zh-
cn/library/vstudio/0b1bf3y3.aspx)
(不同B)----參數不同
方法重構(1)
this.BeginInvoke(Delegate)參數為委托對象,此處和this.Invoke()參數相同(this.Invoke與
this.BeginInovke到底什么不同呢--請繼續看)
方法重構(2)
this.BeginInvoke(Delegate,args)第一個參數同上,第二參數綁定到委托上的方法需要的參數,如果不需要參
數可以傳遞NULL
Delegate.BeginInvoke(異步回調函數--不需要可以為NULL,(不知道要傳遞什么)-null)
看代碼----此處講到在委托綁定的方法中如果遇到大數據量處理或者長時間的Sleep要注意的問題
private Delegate_LED dgate = null;//委托 private Thread myThread;//線程 /// ///構造函數 /// private QueueLED() { myThread = new Thread(new ThreadStart(StartLED));//開啟線程 myThread.IsBackground = true;//后台運行,保證主程序退出時,此線程也會退出 myThread.Start();//線程開始 } private void doFunction() { //your code //循環或者定時處理的或者獲取的數據代碼 Thread.Sleep(1000)------------------------------特別注意到這個地方 }
//線程開始數據處理方法
//------(一)使用this.BeginInvoke()的代碼段-------
private void StartLED() { try { while (true) { if(this.InvokeRequired) { dgate=doFunction;//委托綁定方法,doFunction是你要處理的數據方法 this.BeginInvoke(dgate)//異步執行委托 } else { doFunction(); } Thread.Sleep(100);//循環Sleep } } catch (Exception ex) { LogRecord.RecordLog(ex.Message + ex.Source + ex.InnerException");//異常日志記錄 } }
//------(二)使用Delegate.BeginInvoke()的代碼段-------
private void StartLED() { try { while (true) { dgate = UpdateFun; dgate.BeginInvoke(); Thread.Sleep(100); } } catch (Exception ex) { LogRecord.RecordLog(ex.Message + ex.Source + ex.InnerException");//異常日志記錄 } }
以上代碼看似代碼功能一樣,沒有什么區別(除了宿主線程不同一個是UI一個是自定義線程)--問題出現了?????
首先上幾張圖片給大家(一使用Delegate.Invoke()進程詳情)
十分鍾前--圖片來自Windows任務管理器
十分鍾后
程序運行10分鍾后 圖中1,2 沒有很大變化 3,4變化也很小
再次,使用Delegate.BeginInvoke(null,null)如圖 doFunction方法中的Sleep(1000) 1秒
十分鍾前
十分鍾后
對比結果:1和2變化不大,3和4數值變化不大,但相對於前面兩張圖片數量值增加了
最后,使用Delegate.BeginInvoke(null,null)如圖 doFunction方法中的Sleep(100000)100秒(重點啊)
十分鍾前
十分鍾后
對比結果 :1,2,3,4數據猛增令人不解,先不說與之前的兩次測試結果對比,單這一次,十分鍾之內虛擬內存和句柄數,尤其是線程數 增加令人費解---誰能解釋一下??
所以大家在多線程處理大量並且需要長時間等待情況下,不能使用BeginInvoke(個人意見-如有更好見解請留言-或發郵件