F# 异步 lambda 与 C# 异步模型互操作
F# async lambda interop with C# async model
我有这么一段代码(C#,Pulumi),想翻译成F#:
var registryInfo = repo.RegistryId.Apply(async (id) =>
{
var creds = await GetCredentials.InvokeAsync(new GetCredentialsArgs {RegistryId = id});
var decodedData = Convert.FromBase64String(creds.AuthorizationToken);
var decoded = ASCIIEncoding.ASCII.GetString(decodedData);
var parts = decoded.Split(':');
return new ImageRegistry
{
Server = creds.ProxyEndpoint,
Username = parts[0],
Password = parts[1],
};
});
到目前为止我设法做到的是:
let registryInfo = repo.RegistryId.Apply (fun id -> async {
let! creds = GetCredentialsArgs ( RegistryId = id) |> GetCredentials.InvokeAsync |> Async.AwaitTask
let decodedData = Convert.FromBase64String creds.AuthorizationToken
let decoded = ASCIIEncoding.ASCII.GetString decodedData
let parts = decoded.Split ':'
return ImageRegistry( Server = input creds.ProxyEndpoint, Username= input parts.[0], Password = input parts.[1])
}
)
问题是上面的 F# 代码 returns Output<Async<ImageRegistry>>
,而 C# 代码 returns 预期 Output<ImageRegistry>
。我正在从 C# 过渡到 F#(以扩展我的技能),但我自己无法处理这种情况。这应该如何正确完成?
虽然对 Pulimu API 了解不多,但我猜 Apply
期待 Task<T>
。
您可以使用 Async.StartAsTask
从 F# async 转换为 Task,如下所示:
let registryInfo = repo.RegistryId.Apply (fun id -> async {
//snip
return ImageRegistry( Server = input creds.ProxyEndpoint, Username= input parts.[0], Password = input parts.[1])
} |> Async.StartAsTask
)
尽管如果您正在使用 Task's,您可能会更好地使用 task
计算表达式,而不是使用 Ply (as of writing the native task support is still in development 等库的本机 F# async
。
库 Pulumi.FSharp
为此提供了一个有用的助手 Outputs.applyAsync
:
open Pulumi.FSharp
let registryInfo =
repo.RegistryId |>
Outputs.applyAsync (fun id -> async {
let! creds = GetCredentialsArgs ( RegistryId = id) |> GetCredentials.InvokeAsync |> Async.AwaitTask
let decodedData = Convert.FromBase64String creds.AuthorizationToken
let decoded = ASCIIEncoding.ASCII.GetString decodedData
let parts = decoded.Split ':'
return ImageRegistry( Server = input creds.ProxyEndpoint, Username= input parts.[0], Password = input parts.[1])
})
我有这么一段代码(C#,Pulumi),想翻译成F#:
var registryInfo = repo.RegistryId.Apply(async (id) =>
{
var creds = await GetCredentials.InvokeAsync(new GetCredentialsArgs {RegistryId = id});
var decodedData = Convert.FromBase64String(creds.AuthorizationToken);
var decoded = ASCIIEncoding.ASCII.GetString(decodedData);
var parts = decoded.Split(':');
return new ImageRegistry
{
Server = creds.ProxyEndpoint,
Username = parts[0],
Password = parts[1],
};
});
到目前为止我设法做到的是:
let registryInfo = repo.RegistryId.Apply (fun id -> async {
let! creds = GetCredentialsArgs ( RegistryId = id) |> GetCredentials.InvokeAsync |> Async.AwaitTask
let decodedData = Convert.FromBase64String creds.AuthorizationToken
let decoded = ASCIIEncoding.ASCII.GetString decodedData
let parts = decoded.Split ':'
return ImageRegistry( Server = input creds.ProxyEndpoint, Username= input parts.[0], Password = input parts.[1])
}
)
问题是上面的 F# 代码 returns Output<Async<ImageRegistry>>
,而 C# 代码 returns 预期 Output<ImageRegistry>
。我正在从 C# 过渡到 F#(以扩展我的技能),但我自己无法处理这种情况。这应该如何正确完成?
虽然对 Pulimu API 了解不多,但我猜 Apply
期待 Task<T>
。
您可以使用 Async.StartAsTask
从 F# async 转换为 Task,如下所示:
let registryInfo = repo.RegistryId.Apply (fun id -> async {
//snip
return ImageRegistry( Server = input creds.ProxyEndpoint, Username= input parts.[0], Password = input parts.[1])
} |> Async.StartAsTask
)
尽管如果您正在使用 Task's,您可能会更好地使用 task
计算表达式,而不是使用 Ply (as of writing the native task support is still in development 等库的本机 F# async
。
库 Pulumi.FSharp
为此提供了一个有用的助手 Outputs.applyAsync
:
open Pulumi.FSharp
let registryInfo =
repo.RegistryId |>
Outputs.applyAsync (fun id -> async {
let! creds = GetCredentialsArgs ( RegistryId = id) |> GetCredentials.InvokeAsync |> Async.AwaitTask
let decodedData = Convert.FromBase64String creds.AuthorizationToken
let decoded = ASCIIEncoding.ASCII.GetString decodedData
let parts = decoded.Split ':'
return ImageRegistry( Server = input creds.ProxyEndpoint, Username= input parts.[0], Password = input parts.[1])
})