我想執行一個多次執行阻塞 I/O 操作的庫方法(最多 67840 次呼叫)。該庫不提供該方法的異步版本。
由于在大多數情況下呼叫只是等待超時,我想并行運行多個呼叫。我的方法是異步的,因此如果我能await得到結果就好了。
由于ThreadPool不應用于阻塞操作,我想執行以下操作:
- 啟動多個執行緒(例如 1024)
- 在這些執行緒上運行阻塞呼叫
await完成(例如 viaTaskCompletionSource)并處理正常任務中每個呼叫的結果TheadPool
.NET 中是否有現有的類可以實作這樣的目標?我知道TaskCreationOptions.LongRunning,但據我所知,這將為每次呼叫創建一個新執行緒。
uj5u.com熱心網友回復:
阻塞 I/O 操作...該庫不提供該方法的異步版本。
僅從這一點,您就知道您最終不會得到“理想”的解決方案。理想情況下,I/O 是異步執行的。事實上,在 Windows 上,所有I/O都是在作業系統級別異步執行的,每個同步 API 呼叫只是阻塞當前執行緒,直到異步操作完成。
所以,你應該接受的第一件事是你需要稍微改變規則。
由于在大多數情況下呼叫只是等待超時,我想并行運行多個呼叫。
是的。并行是一個合適的解決方案。如果可以異步執行 I/O,那么并行性將不是合適的解決方案,但是由于 I/O 是阻塞的(并且您無法控制它),那么并行性是您剩下的最佳解決方案.
我的方法是異步的,因此如果我能等待結果就好了。
這不一定遵循。異步方法部分阻塞是可以接受的,只要清楚地記錄下來。異步簽名(即“回傳一個Task”并有一個*Async后綴)暗示該方法可能是異步的,而不是它必須是異步的。
就我個人而言,我不喜歡在我的邏輯方法中進行執行緒卸載,并且只在從 UI 層呼叫它們時才這樣做(鏈接到我的博客)。
由于 ThreadPool 不應該用于阻塞操作
嗯,這是您可以考慮彎曲的規則之一。執行緒池在阻塞操作中確實可以正常作業,實際上這是我建議的第一個解決方案。
啟動多個執行緒(例如 1024)...在這些執行緒上運行阻塞呼叫
如果你放棄“我想要我自己的執行緒”部分而只使用執行緒池,那么答案很簡單:Parallel或者 PLINQ 會很好地作業。您可以為這兩種方法設定最大并行度,并且可以在執行緒池上設定比正常最小執行緒數更大的執行緒數,以便根據需要更快地擴展執行緒數。
這確實會在執行緒池上折騰很多阻塞作業,一般不推薦這樣做,但在某些場景下可以作業。具體來說,像控制臺應用程式或 GUI 應用程式這樣的客戶端應用程式可以很好地作業。但是,如果這是在 Web 應用程式中,那么您不希望通過阻塞呼叫來填充執行緒池。在這種情況下,我實際上建議使用基本的分布式架構(鏈接到我的博客)將掃描拆分為單獨的應用程式。
等待完成(例如通過 TaskCompletionSource)并處理 TheadPool 上正常任務中每個呼叫的結果
如果你想在一個單獨的執行緒上做并行作業,那么你可以把它包裝在await Task.Run(...); 沒有必要與 TCS 混在一起。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/359320.html
標籤:C# 。网 多线程 异步等待 .net-4.7.2
上一篇:掛起和恢復執行緒的問題
