我有一個我正在 vb.net 中撰寫的程式,它已經膨脹成我寫過的最復雜的東西。由于不斷發生一些復雜的數學和影像渲染,我第一次研究多執行緒以提高整體性能。老實說,事情一直運行得非常順利,但我們剛剛添加了更多功能,這給我帶來了一些麻煩。
新功能來自一對 DLL,每個 DLL 處理來自 USB 攝像頭的視頻流并尋找移動物件。當我啟動我的程式時,我啟動了 DLL,它們開始查看攝像機并處理視頻。然后我會定期 ping 他們,看看他們是否檢測到任何東西。這就是我啟動和停止它們的方式:
Declare Function StartLeftCameraDetection Lib "DetectorLibLeft.dll" Alias "StartCameraDetection" () As Integer
Declare Function StopLeftCameraDetection Lib "DetectorLibLeft.dll" Alias "StopCameraDetection" () As Integer
當我需要檢查他們是否找到任何物件時,我會使用如下幾個函式:
Declare Function LeftDetectedObjectLeft Lib "DetectorLibLeft.dll" Alias "DetectedObjectLeft" () As Integer
所有這些都非常有效。問題是,我開始注意到我的 UI 中有一些明顯的滯后,我認為它可能來自 DLL。請原諒我對此的無知,但正如我所說,我是使用多執行緒的新手(老實說,也可以合并 DLL)。在我看來,當我啟動一個 DLL 時,它在我的主執行緒上運行它的后臺任務,并等待我 ping 它以獲取資訊。是這樣嗎?如果是這樣,是否可以讓 DLL 在單獨的執行緒上運行,這樣它就不會影響我的 UI?
我嘗試了一些不同的方法,但似乎無法解決滯后問題。我移動了對 DLL 執行 ping 操作的代碼,并將它獲取的任何資訊處理到一個單獨的執行緒中,但這并沒有任何區別。我還嘗試從單獨的執行緒呼叫 StartLeftCameraDetection,但這似乎也沒有幫助。同樣,我猜這是因為真正的罪魁禍首是 DLL 本身在我的主執行緒上運行這些持續的后臺任務,而不是我實際呼叫它的函式的執行緒。
提前感謝您提供的任何幫助!
uj5u.com熱心網友回復:
在執行緒方面有很多需要了解的地方,但我會嘗試寫一個簡潔的摘要,其中包含足夠的細節以涵蓋您需要了解的內容。
多執行緒同步很難,所以你應該盡量避免它。這并不意味著完全避免多執行緒,它只是意味著避免做更多的事情,而不僅僅是將一個獨立的任務發送到一個執行緒以運行到完成并在完成后回傳結果。
認識到多執行緒同步是困難的,當它涉及 UI 元素時更糟。所以在 .NET 中,設計是對 UI 元素的任何訪問都只能通過一個執行緒進行,通常稱為 UI 執行緒。如果您沒有明確撰寫多執行緒代碼,那么您的所有代碼都在 UI 執行緒上運行。而且,當您的代碼運行時,UI 被阻止。
這也擴展到您運行的外部例程Declare Function。說他們用“主執行緒上的后臺任務”做任何事情并不準確,如果他們用“后臺任務”做任何事情,他們幾乎肯定是在實作自己的執行緒。更有可能的是,他們根本沒有做任何任務分解,他們的所有作業都在你用來呼叫它們的任何執行緒上完成——如果你不做任何其他事情,那就是 UI 執行緒。
如果在這些例程中完成的作業受 CPU 限制,那么將其推送到作業執行緒上肯定是有意義的。根據您對已經嘗試過的內容的評論:
我移動了對 DLL 執行 ping 操作的代碼,并將它獲取的任何資訊處理到一個單獨的執行緒中,但這并沒有任何區別。我還嘗試從單獨的執行緒呼叫 StartLeftCameraDetection,但這似乎也沒有幫助。
我認為最可能的問題是您在 UI 執行緒中阻塞等待來自后臺執行緒的結果。
避免這種情況的最佳方法取決于例程正在做什么以及它們如何產生結果。如果他們執行某種擴展程序并在函式結果中回傳所有內容,那么我建議使用 usingAwait會很好。這基本上會將控制權回傳給 UI,直到操作完成,然后繼續呼叫例程的其余部分將要執行的操作。
請注意,如果您這樣做,用戶將與 UI 進行完全互動,您應該做出相應的反應。在完成之前,您可能需要禁用某些(或全部)操作。
Async和上有很多資源Await。我特別推薦閱讀 Stephen Cleary 的博客文章,以更好地了解它們的作業原理以及您可能遇到的潛在陷阱。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/529159.html
標籤:VB.net多线程dll
上一篇:VBNET長字串中的SQL引數
下一篇:我希望一個函式每天只允許呼叫一次
