请考虑以下代码:

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试图创建一个新的线程池线程吗?(我不确定它是否会这样做.)

推荐答案

将线程池线程设置为1显示了使用do!的异步操作(并且不阻塞当前线程)和同步运行(从而阻塞当前线程)之间的区别.后者不允许执行异步计算(这里:睡眠),因为执行该计算的线程正忙于等待该计算完成:

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

.net相关问答推荐

ASP.NET核心最小API必须以正斜杠开头吗?

C#:如何构造异步/等待代码,其中许多请求是针对相同的、返回缓慢的数据发出的,这可以满足所有请求

CustomControl 计算自己的宽度和高度 - 使用 bounds.Height=0 调用 ArrangeOverride

无法加载文件或程序集 不支持操作. (来自 HRESULT 的异常:0x80131515)

C#字符串的GetHashCode()是如何实现的?

在 .NET 反射中使用 GetProperties() 和 BindingFlags.DeclaredOnly

使用 Task.Factory.StartNew 传递方法参数

使用 Windows 服务和 C# 检测 USB 驱动器插入和移除

我应该默认推荐密封类吗?

如何找到 ManualResetEvent 的状态?

Microsoft.Practices.ServiceLocation 来自哪里?

新的 netstandardapp 和 netcoreapp TFM 有什么区别?

将属性序列化为元素中的 Xml 属性

.NET 的 String.Normalize 有什么作用?

如何将 System.Type 转换为其可为空的版本?

设置 System.Drawing.Color 值

POCO 是什么意思?

CryptographicException 未处理:系统找不到指定的文件

MemoryCache 不遵守配置中的内存限制

为什么 IList 不支持 AddRange