考慮這段代碼:
open System
open System.Threading
ThreadPool.SetMinThreads (1, 1) |> ignore
ThreadPool.SetMaxThreads (1, 1) |> ignore
let asyncOp i = async {
printfn "started %i" i
do! Async.Sleep 1000
printfn "finished %i" i }
for i = 1 to 3 do Async.Start <| asyncOp i
printfn "read"
Console.ReadLine () |> ignore
我理解,用 的檔案來解釋SetMaxThreads,只有一個對執行緒池的請求可以同時處于活動狀態,并且其他請求將保持排隊,直到執行緒可用。它列印
read
started 1
started 2
started 3
finished 3 // after a second
finished 2
finished 1
順便說一句,為什么“完成”的行以相反的順序列印?
現在更改do!為Async.RunSynchronously <|. 這次我們只得到
read
started 1
為什么會停在那里?當您將整行替換為Thread.Sleep 1000:
read
started 1
finished 1 // after a second
started 2
finished 2 // after a second
started 3
finished 3 // after a second
是因為RunSynchronously試圖創建一個新的執行緒池執行緒嗎?(我不確定是否如此。)
uj5u.com熱心網友回復:
do!將執行緒池執行緒設定為 1 顯示了使用(并且不阻塞當前執行緒)和同步運行(因此阻塞當前執行緒)的異步操作之間的區別。后者不允許執行異步計算(此處為:睡眠),因為將執行它的執行緒正忙于等待該計算完成:
open System
open System.Threading
let onThread msg =
let t = Thread.CurrentThread
printfn "%s on thread %i (Pool: %b)" msg t.ManagedThreadId t.IsThreadPoolThread
ThreadPool.SetMinThreads (1, 1) |> ignore
ThreadPool.SetMaxThreads (1, 1) |> ignore
let asyncOp i = async {
printfn "started %i" i
onThread "before sleep" // on thread pool already
let s = Async.Sleep 1000
onThread "going to wait"
Async.RunSynchronously s // blocking THE thread pool thread
onThread "after sleep"
printfn "finished %i" i }
onThread "starting"
for i = 1 to 3 do Async.Start <| asyncOp i
printfn "read"
Console.ReadLine () |> ignore
uj5u.com熱心網友回復:
請注意,切換到 后Async.RunSynchronously,即使只運行一個操作,代碼也會掛起。
ThreadPool.SetMaxThreads檔案狀態:
您不能將作業執行緒或 I/O 完成執行緒的最大數量設定為小于計算機上處??理器數量的數字。
顯然這并不完全正確。您可以將值設定得更低(不會引發例外),但這可能意味著這是一個非常糟糕的主意。但是,我注意到即使將執行緒數增加到 12 或 13,運行 100 個異步操作時代碼仍然掛起。最多 24 個執行緒允許它完成。
對我來說,默認ThreadPool.GetMaxThreads()回傳(32767, 1000)。這向我表明,.NET 執行緒系統確實不是為處理如此少的執行緒而設計的,您不應該將它們減少到接近 1 的任何地方。
SetMaxThreads檔案還說:
更改執行緒池中的最大執行緒數時要小心。雖然您的代碼可能會受益,但更改可能會對您使用的代碼庫產生不利影響。
如果您試圖通過更改 ThreadPool 最大執行緒數來實作特定行為,那么我建議您探索一種不同的方法。
uj5u.com熱心網友回復:
以下是檔案中關于 Async.RunSynchronously 的說明:
何時使用它:
如果您需要它,請在應用程式中僅使用一次 - 在可執行檔案的入口點。當您不關心性能并希望一次執行一組其他異步操作時。
需要注意什么:
呼叫 Async.RunSynchronously 會阻塞呼叫執行緒,直到執行完成。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/513489.html
標籤:。网异步F#睡觉同步
