【问题标题】:F# async lambda interop with C# async modelF# 异步 lambda 与 C# 异步模型互操作
【发布时间】:2023-03-07 05:34:01
【问题描述】:

我有这么一段代码(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#代码返回Output<Async<ImageRegistry>>,而C#代码返回预期的Output<ImageRegistry>。我正在从 C# 过渡到 F#(以扩展我的技能),但我自己无法处理这种情况。这应该如何正确完成?

【问题讨论】:

    标签: c# asynchronous f# pulumi


    【解决方案1】:

    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])
        })
    

    【讨论】:

      【解决方案2】:

      如果不太了解 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 计算表达式而不是原生 F# async 使用诸如 Ply 之类的库(在编写本机任务支持时仍然是 in development) .

      【讨论】:

      • 仍在开发中,但已经准备就绪。猜猜我们很快就会看到它。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      • 2017-01-06
      • 2021-08-31
      • 1970-01-01
      • 1970-01-01
      • 2020-07-24
      相关资源
      最近更新 更多