我在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)
}
我遇到的问题是file
是IAsyncOperation<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#库中执行此操作或某些可用的方法,使其更好一点?
答案 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#核心库很快就能支持它。