请考虑以下代码:

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相关问答推荐

Long.MaxValue从Single到Long的转换导致溢出异常

PowerShell中窗体定时器和系统定时器的统一处理

保存时不保留 XML 格式

如何在 .net MAUI 中删除不需要编译的平台?

在 Rx 中,处理线程安全是否是消费者(IObserver)的责任?

类似于字典但没有值的 C# 数据 struct

在一个 LINQ 查询中获取两列的总和

如何将自定义 UserControl 显示为对话框?

System.String.Copy 在 .NET 中有什么用?

非通用 TaskCompletionSource 或替代

如何使用配置转换删除 ConnectionString

仅使用 XAML 绘制纯色三角形

C# 中的 override 和 new 关键字有什么区别?

在关闭警告中访问 foreach 变量

如何知道 DateTime 是否在 C# 中的 DateRange 之间

了解 C# 中的协变和逆变接口

DateTime.Compare 如何判断日期是否小于 30 天?

IronPython 与 Python .NET

使用 C# vs F# 或 F# vs C# 有什么好处?

如何在我的机器上找到 fuslogvw.exe?