0

我最近一直在使用FSharpx 库,尤其是它的TaskBuilder进行编程。现在我想知道是否应该可以定义一个接受参数并接受结果的函数。如

 let doTask(parameter:int) =
     let task = TaskBuilder(scheduler = TaskScheduler.Current)        
     task {
         return! Task.Factory.StartNew(fun() -> parameter + 1)
     } 

 match FSharpx.Task.run doTask(1) with
 | _ -> ()

查看源代码,我看到run需要一个不带参数并返回Task<'a>. FSharpx TaskTests上似乎也没有示例。

如果有人能建议我应该如何使用 FSharpx 获得这样的场景,或者由于我目前还没有完全理解的原因不应该使用这样的库,我将不胜感激。

<编辑:我相信我可以将 doTask 包装如下

 wrapperDoTask() = doTask(101)
 match FSharpx.Task.run wrapperDoTask with
 | _ -> ()

它可能会起作用。我目前没有使用编译器,所以这有点麻烦。有没有人对任何方向有意见,或者我只是回答了我自己的问题?:)

<edit2: 我想我需要根据MisterMetaphor 的回答再编辑一次。我认为,尤其是他的P.S.消息灵通。我使用 FSharpx TaskBuilder 与 C# 进行互操作,其中,如前所述,任务返回为hot(有一些小例外),已经在运行。这与我最近的问题将 async-await C# 代码翻译成 F# 与调度程序奥尔良有关(我将添加一些标签来加强上下文,也许其他人也在考虑这些)。

当用 C# 术语思考时,我试图实现的是在返回之前等待任务结果,但不会阻塞。我所追求的行为尤其是awaitnot .Result。例如,可以从

试图用 C# 来思考哪个上下文、调度程序或行为或正在发生的事情对我来说有点模糊。不幸的是,在互操作方面,我似乎无法忽略所有细节。:)

4

1 回答 1

2

Task.run仅当您想在当前线程上同步等待任务完成时才需要使用。它需要一个参数,您可以将该参数视为任务工厂——即创建Task<_>. 与 不同Async<_>Task<_>是,它一创建就开始运行。这并不总是一种可取的行为。

您可以使用 实现类似的结果(阻塞等待任务完成)(doTask 101).Result,但我认为Task.runF# 更惯用,它使用Result返回类型来表示错误而不是引发异常。根据情况,可能会争论哪个更好,但根据我在更简单情况下的经验,特殊结果类型比异常更可组合。

这里的另一点是你应该尽可能地避免阻塞等待(Task.run,,, .Wait().Result。(理想情况下,您只在程序的顶层拥有其中之一。)

PS这如果超出了问题的范围,但是您的doTask功能看起来很有趣。task { return! Task.Factory.StartNew( ... ) }相当于Task.Factory.StartNew( ... )。您可能想要做的是task { return parameter + 1 }.

编辑

因此,响应 OP 的问题编辑 :) 如果您需要awaitC# 的行为,您只需要使用let! .... 像这样:

task {
    let! x = someTask 1 2 3
    return x + 5
}
于 2014-07-27T15:25:35.730 回答