我正在尝试使下面的代码正常工作
type Message = {
Text: string
}
[<EntryPoint>]
let main argv =
use bus = RabbitHutch.CreateBus("host=localhost")
async {
let! result = bus.PubSub.PublishAsync({Text = "text"}) |> Async.AwaitTask
}
0
知道PublishAsync
返回Task<unit>
。我只想在F#方法中等效地await
使用此方法,但这会触发错误:
Program.fs(14, 5): [FS0010] Unexpected symbol '}' in expression
我已经检查了that answer on SO,不确定是我应该做什么,添加|> ignore
似乎没有任何作用。
[编辑]
我添加了一个ignore
:
type Message = {
Text: string
}
[<EntryPoint>]
let main argv =
use bus = RabbitHutch.CreateBus("host=localhost")
async {
let! result = bus.PubSub.PublishAsync({Text = "text"}) |> Async.AwaitTask
result |> ignore
}
0
但是现在我收到以下警告:
Program.fs(10, 5)
:[FS0020]
该表达式的结果为'Async<unit>'
类型,被隐式忽略。考虑使用'ignore'
显式丢弃此值,例如'expr |> ignore'
或'let'
将结果绑定到名称,例如'let result = expr'
。
但是,不能摆脱那个想法吗?
答案 0 :(得分:2)
您的async
计算表达式返回Async<unit>
。您需要实际运行计算。您可以使用Async.RunSynchronously
来做到这一点。
async {
let! result = bus.PubSub.PublishAsync({Text = "text"}) |> Async.AwaitTask
result |> ignore
} |> Async.RunSynchronously
尽管在这一点上,我认为计算表达式是多余的。会做同样的事情:
bus.PubSub.PublishAsync({Text = "text"})
|> Async.AwaitTask
|> Async.RunSynchronously
答案 1 :(得分:2)
此表达式的结果:
async {
let! result = bus.PubSub.PublishAsync({Text = "text"}) |> Async.AwaitTask
result |> ignore
}
是Async<unit>
类型的值。在F#和函数式编程中,每个表达式都应有助于更大表达式的结果,否则可能是一个错误。因此,您的编译器报告了警告。
要告诉编译器您还可以,只需使用以下命令将值转换为()
类型的unit
类型(与其他语言的void
类型类似)即可ignore
函数。
现在查看您的async
的主体,在您的旧代码中,最后一条语句为let! result = ...
,并且在F#语法中无效。每个let
或let!
都是let name=... in someExpression
的缩写,但是这里没有表达式,除了}
之外,这就是编译器说Unexpected symbol '}' in expression
的原因。
您通过将result
管道连接到ignore
来解决此问题。没关系,因为这是一个有效的表达式。
现在考虑您的新代码,您可以忽略Async<unit>
以消除该警告,但这会使您的async
变得毫无意义。您声明了async
,但是没有执行它。可能您需要使用Async.RunSynchronously
函数来执行它:
async {
let! result = bus.PubSub.PublishAsync({Text = "text"}) |> Async.AwaitTask
result |> ignore
}
|> Async.RunSynchronously
由于result
是一个unit
值,因此您可以使用do!
清除代码:
async {
do! bus.PubSub.PublishAsync({Text = "text"}) |> Async.AwaitTask
}
|> Async.RunSynchronously
或更干净:
bus.PubSub.PublishAsync({Text = "text"})
|> Async.AwaitTask
|> Async.RunSynchronously