使用F#中的Task.WhenAll重写C#代码

aba*_*hev 8 f# task-parallel-library c#-to-f# async-await

我有以下接口方法:

Task<string[]> GetBlobsFromContainer(string containerName);
Run Code Online (Sandbox Code Playgroud)

及其在C#中的实现:

var container = await _containerClient.GetContainer(containerName);
var tasks = container.ListBlobs()
                     .Cast<CloudBlockBlob>()
                     .Select(b => b.DownloadTextAsync());
return await Task.WhenAll(tasks);
Run Code Online (Sandbox Code Playgroud)

当我尝试在F#中重写它时:

member this.GetBlobsFromContainer(containerName : string) : Task<string[]> =
    let task = async {
        let! container = containerClient.GetContainer(containerName) |> Async.AwaitTask
        return container.ListBlobs()
               |> Seq.cast<CloudBlockBlob>
               |> Seq.map (fun b -> b.DownloadTextAsync())
               |> ??
    }
    task |> ??
Run Code Online (Sandbox Code Playgroud)

我坚持最后一行.

如何正确返回Task<string[]>F#?

Car*_*Dev 7

我不得不猜测它的类型containerClient和最接近的是什么CloudBlobClient(它没有,getContainer: string -> Task<CloubBlobContainer>但它不应该太难以适应).然后,您的函数可能如下所示:

open System
open System.Threading.Tasks
open Microsoft.WindowsAzure.Storage.Blob
open Microsoft.WindowsAzure.Storage

let containerClient : CloudBlobClient = null

let GetBlobsFromContainer(containerName : string) : Task<string[]> =
    async {
        let container = containerClient.GetContainerReference(containerName)
        return! container.ListBlobs()
               |> Seq.cast<CloudBlockBlob>
               |> Seq.map (fun b -> b.DownloadTextAsync() |> Async.AwaitTask)
               |> Async.Parallel
    } |> Async.StartAsTask
Run Code Online (Sandbox Code Playgroud)

我改变了返回类型,Task<string[]>而不是Task<string seq>因为我想要保留接口.否则,我建议摆脱F#-only代码Task并使用Async它.