我有一个 C# 语言的 WPF 应用程序 (.NET 8)。此应用程序调用 F# 库中的函数,此 F# 函数使用 backgroundTask 计算表达式启动任务:
let fun1() = ignore <| backgroundTask {
// long asynchronous work, no access elements, only internal memory
}
通过使用
backgroundTask
而不是 task
CE,我希望任务在单独的线程上运行,并且 不会影响 GUI 的响应能力。
但情况并非如此,该任务运行时 GUI 仍然冻结。
怎么了?
您的场景中
SynchronizationContext.Current
的价值是多少?
来自 F# 文档:
后台任务会在以下意义上忽略任何
:如果在具有非空SynchronizationContext.Current
的线程上启动,它将使用SynchronizationContext.Current
切换到线程池中的后台线程。如果在带有 nullTask.Run
的线程上启动,它将在同一线程上执行。SynchronizationContext.Current
鉴于此解释,我怀疑您有一个 null
SynchronizationContext.Current
,因此您的代码正在启动它的线程上运行。 (我也发现这种行为令人惊讶,但至少它被记录下来。)
经过一番调查,我终于在 GUI 中获得了所需的流畅性。这是我发现的:
现在,如果我运行我的新代码(无 TaskSeq),发布版本,不附加调试器,则根本不会发生冻结(或者是察觉不到的)。