Итак, немного поработав с моделью Async
в F#, я думаю, что обдумал ее и ее отличия от модели Task
в C#. Одна из вещей, которые мне действительно нравятся в том, как они взаимодействуют, это Async.AwaitTask
:
...
public Task<int> SomeCsharpApiAsync() {
...
}
...
let someFsharpAsyncCode = async {
let! someResult = Async.AwaitTask (SomeClass.SomeCsharpApiAsync())
return someResult
}
В приведенном выше коде строка, вызывающая AwaitTask, не только ожидает завершения задачи, но и присваивает ее результат переменной someResult
в операции, которую я считаю атомарной. Очень аккуратный!
Однако у меня возникла проблема с достижением того же (атомарность, поэтому отсутствие условий гонки) при использовании Task.WhenAny
:
...
public Task<int> SomeCsharpApiAsync(string someParam) {
...
}
...
let someFsharpAsyncCode = async {
let task1 = SomeClass.SomeCsharpApiAsync "foo"
let task2 = SomeClass.SomeCsharpApiAsync "bar"
let! fastestTask = Async.AwaitTask (Task.WhenAny([task1;task2]))
return fastestTask.Result
}
Проблема с приведенным выше кодом заключается в том, что операция AwaitTask
возвращает задачу (самую быструю), а не результат, поэтому это дополнительный уровень косвенности, который я разрешаю, вызывая .Result
позже. Но я нашел проблемы по этому поводу, виновником которых, я думаю, являются условия гонки: самая быстрая задача может иметь какой-то результат в этот момент, но при получении ее результата мог быть запрошен (отменен) маркер отмены задачи! Или самая быстрая задача была быстрее, потому что на самом деле та была отменена быстрее? Я не уверен, и я немного не понимаю, как понять, что здесь происходит.
Может быть, я могу вообще избежать этой проблемы, используя альтернативу F# Task.WhenAny
в C#?
1 ответ
Посмотрите, может ли эта реализация Async.WhenAny решить вашу проблему: https://github.com/tpetricek/ TryJoinads/blob/master/src/FSharp.Joinads/Async.fs#L9
См. также этот блог: http://tomasp.net/blog/joinads-async- реализовать.aspx/
Этот пример очень похож на ваш код, но, возможно, есть небольшая разница: https://github.com/microsoft/fsharplu/blob/master/FSharpLu/Async.fs#L59
А вот еще один краткий пример с другой целью, но все же может быть полезен: http://www.fssnip.net/hx/title/AsyncAwaitTask-with- тайм-ауты
Похожие вопросы
Новые вопросы
asynchronous
Асинхронное программирование - это стратегия для отсрочки операций с высокой задержкой или низким приоритетом, обычно в попытке улучшить производительность, скорость отклика и / или совместимость программного обеспечения. Такие стратегии обычно используются, используя некоторую комбинацию управляемого событиями программирования и обратных вызовов, и, возможно, используя параллелизм через сопрограммы и / или потоки.