gpt4 book ai didi

wcf - 在 F# 中使用 IDisposable 是否需要使用 async 关键字?

转载 作者:行者123 更新时间:2023-12-04 22:05:29 25 4
gpt4 key购买 nike

我得到一个 Cannot access a disposed object运行以下代码时出错(MyClient 是由 C# 项目中的服务引用生成的 WCF 客户端)。

type Action =
| Add
| Update

let addStuff (myClient:MyClient) arg = async {
let! response = myClient.AddAsync arg |> Async.AwaitTask
return response.ID
}

let updateStuff (myClient:MyClient) arg = async {
let! response = myClient.UpdateAsync arg |> Async.AwaitTask
return response.ID
}

let doStuff arg =
use myClient = new MyClient()
match arg.Action with
| Add -> arg |> addStuff myClient
| Update -> arg |> updateStuff myClient

let args = [Add, Add, Update, Add]

let results =
args
|> List.map doStuff
|> Async.Parallel

看来客户端在我预期之前就被处理掉了。如果我改变 doStuff到:

let doStuff arg = async {
use myClient = new MyClient()
return!
match arg.Action with
| Add -> arg |> addStuff myClient
| Update -> arg |> updateStuff myClient
}

两个函数的返回类型都是Async<int> .为什么客户端在第一个示例中提前处理?我认为这两个例子在逻辑上是相同的。我的理解是 async只有在需要使用 ! 时才需要工作流程我认为在这种情况下不需要绑定(bind),因为实际等待发生在特定函数中。

最佳答案

问题出在doStuff:

let doStuff arg =
use myClient = new MyClient()
match arg.Action with
| Add -> arg |> addStuff myClient
| Update -> arg |> updateStuff myClient

您正在将 myClient 传递到捕获 MyClient 实例的异步函数中。但是,当 doStuff 返回时,它会调用 MyClient 实例上的 Dispose 并释放客户端。当您的异步方法开始运行时,它正在使用已处置的实例。

使 doStuff 起作用是因为处置成为异步工作流的一部分。

另一种选择是不使用 MyClient 实例,而是让 addStuffupdateStuff 创建它们自己的实例MyClient 实例。

关于wcf - 在 F# 中使用 IDisposable 是否需要使用 async 关键字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48648866/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com