Ожидание операции IAsyncOperation в F#
У меня есть следующий код в 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);
}
Проблема в том, что я не знаю, как ждать IAsyncOperation
в F#. Обычный 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 ответ
Ваше решение мне кажется хорошим. Если вы ищете более приятный синтаксис, как насчет того, чтобы свернуть его в функцию, подобную этой (без каких-либо необоснованных аннотаций типов):
let await<'a> (op: IAsyncOperation<'a>) : Async<'a> =
op.AsTask() |> Async.AwaitTask
Это даст вам почти такой же синтаксис, который вы видели бы в C#:
async {
let! file = await <| StorageFile.GetFileFromApplicationUriAsync(uri)
...
}
Ошибки компилятора, которые вы получали с вашими предыдущими подходами, следует ожидать. Все, что касается асинхронного рабочего процесса, - это F#-специфический тип асинхронности. Этот тип дает вам возможность взаимодействовать с остальным миром.NET с помощью задач, но это все. IAsyncOperation из "другой части мира", я не ожидаю, что основные библиотеки F# поддержат ее в ближайшее время.