none
關於 thread 和 threadpool RRS feed

  • 問題

  • 我現在有一個 會執行 比較久的 method 

    public void DataReceived(Object o)

    這個 method 被呼叫是在  有event 發生時  例如 : 股價進來時

    我在那個 event 中這樣寫

    //接收股價進來

    private void qtPush_DataReceived(string[] TagValue)
            {

            ThreadPool.QueueUserWorkItem(new WaitCallback(DataReceived), TagValue);           

            }

    發現  股價是進來的很快 擺到 threadpool 中 但 畫面在處理時 好像是從上到下一筆一筆的處理

    感覺 只是 畫面沒有被 鎖住 但 跑得滿慢的

    在我的觀念中 應該是要 multithread 啊  是否 我有什麼地方寫錯

    或者有更好的方法

    2010年3月31日 上午 08:16

解答

  • Hi,

    可搭配上面提到的Virtual Mode再想想看

    當資料要顯示時CellValueNeeded的事件觸發

    其參數可判斷出要顯示的欄位

    藉此推算是哪隻股票

    再去查看該股票是否有新進的股價

    有的話就計算顯示

    沒有的話就回傳之前算好的資料


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/
    • 已標示為解答 布利 2010年4月5日 下午 12:46
    • 已標示為解答 布利 2010年4月5日 下午 12:46
    2010年4月2日 上午 04:26

所有回覆

  • multithread也需要時間在各個不同的Thread中切換的. 當牽扯到畫面變動時, 通常慢的原因會出在如何繫結資料到畫面上.

    打個比方來說, 如果你每次畫面變動就要把資料庫重新讀一次, 那一定會比只更新有變動的來得慢.

    或是你一次變動十筆, 如果你是一筆一筆加入畫面, 也會比一次加十筆進畫面來得慢


    MSDN 文件庫很重要
    回應幫助你的人是一種禮貌, 良好的禮貌有助於激發大家對你問題回應的熱情
    進步的人會找尋自己程式中的缺點,半桶水則把自己程式的錯誤推到不相干事物的身上
    2010年3月31日 上午 08:34
    版主
  • multithread也需要時間在各個不同的Thread中切換的. 當牽扯到畫面變動時, 通常慢的原因會出在如何繫結資料到畫面上.

    打個比方來說, 如果你每次畫面變動就要把資料庫重新讀一次, 那一定會比只更新有變動的來得慢.

    或是你一次變動十筆, 如果你是一筆一筆加入畫面, 也會比一次加十筆進畫面來得慢


    MSDN 文件庫很重要
    回應幫助你的人是一種禮貌, 良好的禮貌有助於激發大家對你問題回應的熱情
    進步的人會找尋自己程式中的缺點,半桶水則把自己程式的錯誤推到不相干事物的身上


    我基本上是去改 Datagridview 的 row 值 不會去重新載入

    想請較您  有辦法讓速度上加快嘛  因為感覺 還是一筆一筆在處理 

     

    2010年3月31日 上午 08:38
  • Hi,

    從您的資料我只看到把一個不知名的方法丟進ThreadPool

    看不出該方法所做的動作...

     

    另外一提,你是用資料繫結嗎?

    若不是的話,可加加看BeginEdit與EndEdit

    DataRow.BeginEdit 方法

    http://msdn.microsoft.com/zh-tw/library/system.data.datarow.beginedit.aspx

    DataRow.EndEdit 方法

    http://msdn.microsoft.com/zh-tw/library/system.data.datarow.endedit.aspx


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/
    2010年3月31日 上午 09:32
  • Hi,

    從您的資料我只看到把一個不知名的方法丟進ThreadPool

    看不出該方法所做的動作...

     

    另外一提,你是用資料繫結嗎?

    若不是的話,可加加看BeginEdit與EndEdit

    DataRow.BeginEdit 方法

    http://msdn.microsoft.com/zh-tw/library/system.data.datarow.beginedit.aspx

    DataRow.EndEdit 方法

    http://msdn.microsoft.com/zh-tw/library/system.data.datarow.endedit.aspx


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/


    感謝您的提醒

    因為 那個method 的程式碼  很長

    貼上來 太多了

    主要是做

    1. 接到 股價後 進行 損益的運算 還有 其它 Greeks 的運算

       運算完後 會把 資料 更新回  DataTable 中 對應的 Datarow

       所以 我把這些一收到股價的動作  丟到  threadPool  以防止 畫面會卡住

       現在 發現  好像  上到下一筆一筆的處理 不是 加新的row 是更新 row 的資料

       感覺 慢慢的

       是否  有其它的好方法可以去思考呢

      

    2010年3月31日 下午 12:03
  • Hi,

    不是 加新的row 是更新 row 的資料

    這句話的意思是...?

    我想知道您介面怎摸更新的?

    是繫上DataSource後去改DataTable的DataRow?

    還是改完DataTable的DataRow後再繫上?

    或是直接用填值的方式把資料填到DataGridView?

     

    另外,您每收到一筆股價,就要大量的運算?

    運算是否有辦法優化或是批次處理?

    也可以查詢一下DataGridView的VirtualMode技術


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/
    2010年3月31日 下午 03:02
  • Hi,

    不是 加新的row 是更新 row 的資料

    這句話的意思是...?

    我想知道您介面怎摸更新的?

    是繫上DataSource後去改DataTable的DataRow?

    還是改完DataTable的DataRow後再繫上?

    或是直接用填值的方式把資料填到DataGridView?

     

    另外,您每收到一筆股價,就要大量的運算?

    運算是否有辦法優化或是批次處理?

    也可以查詢一下DataGridView的VirtualMode技術


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/

    我是用這個方法的  是繫上DataSource後去改DataTable的DataRow

    其實 我是很納悶  為何 ThreadPool  並沒有加快速度  反而  一筆一筆處理的感覺~~~

    至於  因為 股價  是很多 Greeks 運算的 參數之一  那些  運算  往往都會花到時間  因為 要跑財工的一些運算

    優化 應該沒辦法 

    還有  VirtualMode 是什麼啊   對我這個問題  能有幫助嘛

    再次感謝您的回答  ~~~

    2010年3月31日 下午 03:24
  • Hi,

    執行緒的觀念我還是很不熟

    下面看看就好

     

    我是覺得您的寫法只是把主執行緒要處理的動作

    丟到另一個執行緒

    就像是您要去公家機關辦事情

    本來要給A櫃台做的事

    轉交給B櫃檯去做

    換個人做而已

    就算A櫃台與B櫃台可以同時處理

    可是要辦的事情沒有切開同時給兩個人處理

    辦完事情要花的時間仍舊沒變

    但當要辦的事情不只一件時

    A櫃台與B櫃台就可以同時處理

     

    個人是覺得如果運算量過大,使用多執行緒可能會有幫助

    但效果仍是有限,若是演算法不夠好,也沒辦法達到滿意的效能

    有些龐大的運算或許可以透過記些資料去簡化處理動作

    像是做總合的部分

    每次都從頭加起

    跟拿記錄的上次總合加上這次加入的資料

    這兩種方法就有差異

    有些時候花點記憶體做些快取

    是可以加快運算的動作的

     

    另外Virtual Mode可以只加載要顯示的部分

    可加快資料顯示的速度

     

    可參閱

    DataGridView中虚拟模式(Virtual Mode)的使用

    http://www.cnblogs.com/maweifeng/archive/2006/09/17/506574.html


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/
    2010年3月31日 下午 04:07
  • Hi,

    執行緒的觀念我還是很不熟

    下面看看就好

     

     

    我是覺得您的寫法只是把主執行緒要處理的動作

    丟到另一個執行緒

    就像是您要去公家機關辦事情

    本來要給A櫃台做的事

    轉交給B櫃檯去做

    換個人做而已

    就算A櫃台與B櫃台可以同時處理

    可是要辦的事情沒有切開同時給兩個人處理

    辦完事情要花的時間仍舊沒變

    但當要辦的事情不只一件時

    A櫃台與B櫃台就可以同時處理

     

     

    個人是覺得如果運算量過大,使用多執行緒可能會有幫助

    但效果仍是有限,若是演算法不夠好,也沒辦法達到滿意的效能

    有些龐大的運算或許可以透過記些資料去簡化處理動作

    像是做總合的部分

    每次都從頭加起

    跟拿記錄的上次總合加上這次加入的資料

    這兩種方法就有差異

    有些時候花點記憶體做些快取

    是可以加快運算的動作的

     

    另外Virtual Mode可以只加載要顯示的部分

    可加快資料顯示的速度

     

    可參閱

    DataGridView中虚拟模式(Virtual Mode)的使用

    http://www.cnblogs.com/maweifeng/archive/2006/09/17/506574.html


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/


    謝謝您的回應

    那請較   各位  高手們   還有什麼方向能去改善嘛

    特別是  Threadpool 的使用  是否 我用的方式不對 還是 有更好的方式 讓效率能加快呢?!

    2010年4月1日 上午 12:01
  • 我提供另一個想法,您可以參考看看!

    我剛看了諸位前輩的討論,讓我想到了,如果都是大量的運算,不外乎使用演算法來增進其運算效益外,要不然就是把前一次與本次新增的資料看是否有什麼公式之類的把值算出來。

    而我想提供的想法是,有些運算內容是否能交給 DB Engine 來輔助運算,然後把最後結果寫入 DB 的欄位中,過來再搭上 SqlDependency 及 SqlCacheDependency 類別,讓 DB 與 UI 間可以即時呈現資訊及其差異處。

    這樣一來,DB 可記錄您所有的欲記錄資料及結果外,也應該能讓 UI 可馬上呈現資訊而不致於過慢!!!  你可以參考看看~


    逐步學習,逐夢踏實;腳步要踩穩,這樣下一步才不會跌倒。 http://www.dotblogs.com.tw/nobel12
    2010年4月1日 上午 01:28
  • 我提供另一個想法,您可以參考看看!

    我剛看了諸位前輩的討論,讓我想到了,如果都是大量的運算,不外乎使用演算法來增進其運算效益外,要不然就是把前一次與本次新增的資料看是否有什麼公式之類的把值算出來。

    而我想提供的想法是,有些運算內容是否能交給 DB Engine 來輔助運算,然後把最後結果寫入 DB 的欄位中,過來再搭上 SqlDependency 及 SqlCacheDependency 類別,讓 DB 與 UI 間可以即時呈現資訊及其差異處。

    這樣一來,DB 可記錄您所有的欲記錄資料及結果外,也應該能讓 UI 可馬上呈現資訊而不致於過慢!!!  你可以參考看看~


    逐步學習,逐夢踏實;腳步要踩穩,這樣下一步才不會跌倒。 http://www.dotblogs.com.tw/nobel12


    這個  我有想過 可是資料庫是 sql2000 好像不能用這個功能

    但 還是很謝謝您

    2010年4月1日 上午 02:50
  • Hi,

    再提供一個想法

    當收到股價資料時

    不要全部都拿去運算更新

    可以只對目前有顯示的去更新

    沒有顯示的部分就記在記憶體中

    當需要顯示時再做運算

    不然收到100筆股價

    畫面只夠顯示10筆

    其餘90筆的仍做運算更新

    是不必要的浪費

    尤其當未顯示的股價持續的變更

    這些運算都是多餘的

    只有顯示前最後一次收到股價才是要運算要顯示的


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/
    2010年4月1日 下午 02:32
  • Hi,

    再提供一個想法

    當收到股價資料時

    不要全部都拿去運算更新

    可以只對目前有顯示的去更新

    沒有顯示的部分就記在記憶體中

    當需要顯示時再做運算

    不然收到100筆股價

    畫面只夠顯示10筆

    其餘90筆的仍做運算更新

    是不必要的浪費

    尤其當未顯示的股價持續的變更

    這些運算都是多餘的

    只有顯示前最後一次收到股價才是要運算要顯示的


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/

    只有顯示前最後一次收到股價才是要運算要顯示的

    使用者 會捲動畫面  這樣 不是很難判斷  "顯示前" 這個事件?!

    但 這個方法  還真不賴  要好好再想想 謝啦~~~

    2010年4月1日 下午 03:30
  • Hi,

    可搭配上面提到的Virtual Mode再想想看

    當資料要顯示時CellValueNeeded的事件觸發

    其參數可判斷出要顯示的欄位

    藉此推算是哪隻股票

    再去查看該股票是否有新進的股價

    有的話就計算顯示

    沒有的話就回傳之前算好的資料


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/
    • 已標示為解答 布利 2010年4月5日 下午 12:46
    • 已標示為解答 布利 2010年4月5日 下午 12:46
    2010年4月2日 上午 04:26