等待F#中的IAsyncOperation

时间:2014-04-26 15:31:41

标签: f# windows-store-apps async-await iasyncoperation

我在F#中有以下代码:

   let CreateSampleDataFromJson<'T>(path) = 
      let uri = new Uri(path)
      async {
         let file = StorageFile.GetFileFromApplicationUriAsync(uri)
         let jsonText = FileIO.ReadTextAsync(file)
         return JsonObject<'T>.Parse(jsonText)
      }

我遇到的问题是fileIAsyncOperation<StorageFile>,而StorageFile不是ReadTextAsync

在C#中你可以做类似的事情:

var file = await StorageFile.GetFileFromApplicationUriAsync(uri) 

public async Task<T> CreateSampleDataFromUrl<T>(string path)
{
  var uri = new Uri(path);
  var file = await StorageFile.GetFileFromApplicationUriAsync(uri);
  var jsonText = await FileIO.ReadTextAsync(file);
  return JsonObject<T>.Parse(jsonText);
}

问题在于我不知道如何在F#中等待IAsyncOperation。通常的let!不起作用。即以下未能编译:

async {
   let! file = StorageFile.GetFileFromApplicationUriAsync(uri)

编译错误:

error FS0001: This expression was expected to have type    Async<'a>    but here has type    IAsyncOperation<StorageFile>

我找到了一个文档,说明AsTask()类中定义了System.WindowsRuntimeSystemExtensions扩展方法,我可以按如下方式使用:

 let! file = StorageFile.GetFileFromApplicationUriAsync(uri).AsTask() |> Async.AwaitTask

是否有一种标准方法可以在F#库中执行此操作或某些可用的方法,使其更好一点?

1 个答案:

答案 0 :(得分:1)

我的解决方案似乎很好。如果您正在寻找更好的语法,那么如何将其转换为这样的函数(没有可能无偿的类型注释):

let await<'a> (op: IAsyncOperation<'a>) : Async<'a> =
   op.AsTask() |> Async.AwaitTask

这将为您提供与c#:

中几乎完全相同的语法
async {
   let! file = await <| StorageFile.GetFileFromApplicationUriAsync(uri)
   ...
}

您需要使用以前的方法获得的编译器错误。所有异步工作流程都关注的是F#特定的异步类型。这种类型为您提供了一种通过任务与.NET世界的其余部分互操作的方法,但就是这样。 IAsyncOperation来自世界不同的地方,我不希望F#核心库很快就能支持它。