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

时间:2015-08-09 05:43:42

标签: f# async-await task-parallel-library c#-to-f#

我有以下界面方法:

Task<string[]> GetBlobsFromContainer(string containerName);

及其在C#中的实现:

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

当我尝试在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 |> ??

我坚持最后一行。

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

2 个答案:

答案 0 :(得分:6)

我不得不猜测================================================== YearMonth LocationCode Active New =================================================== 201405 123 0 0 201406 123 2 1 201409 211 1 0 201410 211 0 0 201411 214 0 0 201412 214 3 1 的类型是什么,我找到的最近的是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 而不是Task<string[]>,因为我想您要保留界面。否则,我建议删除Task<string seq>并在F#-only代码中使用Task

答案 1 :(得分:4)

这会有用吗?

 IEnumerator WaitingForSomething()
     {
         UnityEngine.Debug.Log("Before Waiting");
         yield return new WaitForSeconds(2);
         UnityEngine.Debug.Log("After Waiting");
         print(Time.time);
     }

我不得不对member this.GetBlobsFromContainer(containerName : string) : Task<string seq> = let aMap f x = async { let! a = x return f a } let task = async { let! container = containerClient.GetContainer(containerName) |> Async.AwaitTask return! container.ListBlobs() |> Seq.cast<CloudBlockBlob> |> Seq.map (fun b -> b.DownloadTextAsync() |> Async.AwaitTask) |> Async.Parallel |> aMap Array.toSeq } task |> Async.StartAsTask 等作出一些假设,所以我无法对此进行测试,但至少它会编译。