Я получаю данные из API Bloomberg, и меня очень удивляет медлительность.Мое вычисление - это ввод-вывод, ограниченный этим.
Поэтому я решил использовать какой-нибудь асинхронный монадный конструктор, чтобы отменить его.После его запуска результаты не намного лучше, что было очевидно, поскольку я выполняю вызов функции NextEvent, которая блокирует потоки.
let outerloop args dic =
...
let rec innerloop continuetoloop =
let eventObj = session.NextEvent(); //This blocks
...
let seqtable = reader.ReadFile( @"C:\homeware\sector.csv", ";".[0], true)
let dic = ConcurrentDictionary<_,_> ()
let wf = seqtable |> Seq.mapi (fun i item -> async { outerloop item dic } )
wf |> Async.Parallel
|> Async.RunSynchronously
|> ignore
printfn "%A" ret
Есть ли хороший способ обернуть этот блокирующий вызовна неблокирующий звонок?Кроме того, почему асинхронная среда не создает столько потоков, сколько у меня запросов (например, 200)?когда я проверяю потоки, из которых я получаю значения, я вижу только 4-5, которые используются ..
ОБНОВЛЕНИЕ
Я нашел убедительную причину того, что он никогда не будетбыть возможнымАсинхронная операция берет то, что находится после асинхронной инструкции, и планирует это где-то в пуле потоков.для всего, что имеет значение, если асинхронная функция используется правильно, то есть всегда возвращаться к пулу потоков, из которого она возникла, мы можем считать, что выполняемся в одном потоке.
Нахождение в одном потоке означаетвсе это планирование всегда будет выполняться где-то позже, и инструкция по блокировке не может избежать того факта, что, в конце концов, после выполнения ей в какой-то момент в будущем придется заблокировать поток операций.