最近在寫乙個http介面時用了datatable這個強大的利器,介面用瀏覽器跑起來沒任何問題。當時也沒考慮併發問題,後來用乙個壓力測試工具做大併發測試,1000+/s次速度測試。發現程式報錯了。程式報錯了第一反應還是去檢查**,是不是**出現問題。發現邏輯都是對的,然後用瀏覽器開啟介面,發現一切ok;然後心想肯定是併發時多個執行緒操作導致的。
我們都知道在多執行緒的時候不同的執行緒訪問同乙個資源的時候,用lock方法來達到執行緒同步,也就是同乙個時刻同乙個資源只能被乙個執行緒操作。
我開始在操作datatable的函式前面加上:
1object oblock = new
object();23
lock
(oblock)
4
信心滿滿的開始繼續用壓力測試工具來測試。結果還是報錯;因為是併發操作你幾乎不能用vs進行斷點除錯;所以也不好找到具體的錯誤在什麼地方。然後就try catch 列印錯誤日誌找到具體異常原因和所在**行。提示的錯誤有時候都不盡相同;有「內部索引損壞」、"在位置0處沒有任何行" 等等。加了lock還報錯就感覺挺納悶的;當這段**被鎖定以後應該是不會被其他執行緒操作,也就不會導致行的索引出現問題。
後來找些資料發現,因為我們平時對datatable的操作基本是rows操作,所以我上面lock的**裡面只鎖定了datatable的rows;但是因為我沒有操作columns,所以其他執行緒還可以訪問datatable的columns集合。但是rows是共享乙個columns的;罪魁禍首應該是沒有鎖住columns導致的。
解決方法:
所以我們只需要在要操作datatable**的前面加上:
1 //你要操作的 datatable2 datatable
dtb =new
datatable();
3 lock(dtb.rows.syncroot)
4
注:並不是所有datatable在多執行緒操作是都會報錯;視具體情況而定。但是為了執行緒安全在多執行緒下操作是最好加上rows.syncroot
鎖。
多執行緒訪問DataTable
專案中需要讀取資料庫中的多張表。由於表的資料比較多,序列讀取時耗時比較多,所以對程式做了一點優化。環境.net 3.5,sql server 2012,visual studio 2015 過程專案中使用儲存過程序列地讀取資料庫,儲存過程接受同乙個表變數作為引數。但是當在多執行緒中複製datatab...
C 多執行緒操作
在.net和c 中編寫乙個多執行緒應用程式將非常得容易。即使對於那些從沒有用c 編寫過多執行緒應用程式的初學者,只需遵循以下這些簡單的步驟就可以實現目的。定義命名空間 在.net中,多執行緒功能是在system.threading命名空間中定義的。因此,在使用任何執行緒類之前,必須定義 system...
多執行緒操作磁碟
最近要寫乙個多執行緒的應用,需要從幾十塊磁碟中讀取資料,每次只將5塊盤中的資料進行加工整合,而且磁碟的讀取都是隨機的,不是順序的。加工後需要將結果寫入乙個大的儲存中,n個t。原來我寫的是單執行緒的,速度好慢1分鐘只能處理3g左右或者不到。業務做起來相當的費時費力,leader叫我改多執行緒,一時間沒...