簡體   English   中英

在 Delphi 中,TDataSet 線程安全嗎?

[英]In Delphi, is TDataSet thread safe?

我希望能夠在它自己的線程中異步打開一個 TDataSet,以便主 VCL 線程可以繼續直到完成,然后從該 TDataSet 讀取主 VCL 線程。 我做了一些實驗,遇到了一些非常奇怪的情況,所以我想知道以前是否有人這樣做過。

我見過一些示例應用程序,其中 TDataSet 在單獨的線程中創建,它被打開,然后從中讀取數據,但這都是在單獨的線程中完成的。 我想知道在另一個線程打開數據源后從主 VCL 線程讀取 TDataSet 是否安全。

我正在 Delphi 7 中進行 Win32 編程,使用來自DAC for MySQL 的TmySQLQuery 作為我的 TDataSet 后代。

假設您只想在自己的線程中使用數據集,您可以使用同步與主線程通信以進行任何 VCL/UI 更新,就像與任何其他組件一樣。
或者,更好的是,您可以使用自己的消息傳遞系統實現主線程和工作線程之間的通信。

在此處檢查 Hallvard 的線程解決方案:
http://hallvards.blogspot.com/2008/03/tdm6-knitting-your-own-threads.html

或另一個:
http://dn.codegear.com/article/22411

有關同步及其低效的一些解釋:
http://www.eonclash.com/Tutorials/Multithreading/MartinHarvey1.1/Ch3.html

我已經看到它與 TDataSet 的其他實現一起完成,即在Asta組件中。 這些將聯系服務器,立即返回,然后在加載數據后觸發一個事件。

但是,我相信這在很大程度上取決於組件。 例如,除了主 VCL 線程之外,無法以同步方式打開那些相同的 Asta 組件。

簡而言之,我不認為這是 TDataSet 本身的限制,而是特定於實現的東西,我無權訪問您提到的組件。

在多個線程之間使用相同的TDataSet 時要記住的一件事是您只能在任何給定時間讀取當前記錄。 因此,如果您在一個線程中讀取記錄,然后另一個線程調用Next,那么您就有麻煩了。

還要記住,線程很可能需要自己的數據庫連接。 我相信這里需要的是一個多線程“保持”對象來將數據從線程加載到(只寫)中,然后只能從主 VCL 線程讀取。 在閱讀之前使用某種同步方法來確保你不會在你寫作的同時閱讀,或者在你閱讀的同時寫作,或者將所有內容加載到內存文件中並編寫一個同步方法來告訴主應用程序在文件中的位置停止閱讀。

我已經多次采用最后一種方法,這取決於預期記錄的數量(和數據集的大小),我什至將它帶到了本地系統上的物理磁盤文件中。 它運作良好。

我已經做過多線程數據訪問,它並不簡單:

1)您需要為每個線程創建一個會話。

2) 對該 TDataSet 實例所做的一切都必須在創建它的線程的上下文中完成。 如果您想在它上面放置例如一個 db 網格,這並不容易。

3)如果您想讓例如主線程處理您的數據,直接的解決方案是將其移動到某種單獨的容器中,例如內存數據集。

4)一旦數據檢索完成,您需要某種信號機制來通知主線程。

……而且異常處理也不是那么簡單……

但是:一旦你成功了,應用程序將會非常優雅!

大多數 TDataset 不是線程安全的。 我知道線程安全的一個是kbmMemtable 它還具有克隆數據集的能力,因此確實會出現移動記錄指針的問題(如 Jim McKeeth 所解釋)。 它們是您可以獲得(購買或免費)的最佳數據集之一。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM