Pergunta

Vamos dizer que eu queria raspar uma página web, e extrair alguns dados. Eu ia escrever algo mais provável como esta:

let getAllHyperlinks(url:string) =
    async {  let req = WebRequest.Create(url)
             let! rsp = req.GetResponseAsync()
             use stream = rsp.GetResponseStream()             // depends on rsp
             use reader = new System.IO.StreamReader(stream)  // depends on stream
             let! data = reader.AsyncReadToEnd()              // depends on reader
             return extractAllUrls(data) }                    // depends on data

O let! diz F # para executar o código em outro segmento, em seguida, ligam o resultado a uma variável, e continuar o processamento. O exemplo acima usa duas declarações let: um para obter a resposta, e um para ler todos os dados, de modo que ele gera pelo menos dois tópicos (por favor me corrijam se eu estiver errado)

.

Embora o fluxo de trabalho acima gera vários threads, a ordem de execução é de série, porque cada item no fluxo de trabalho depende do item anterior. Não é realmente possível avaliar todos os itens ainda mais para baixo o fluxo de trabalho até que os outros tópicos retornar.

Há algum benefício para ter mais de um let! no código acima?

Se não, como é que esta necessidade código para alterar para tirar proveito de várias instruções let!?

Foi útil?

Solução

A chave é que são não desova quaisquer novos tópicos. Durante todo o curso do fluxo de trabalho, há 1 ou 0 tópicos ativos que estão sendo consumidos a partir do ThreadPool. (Uma exceção, até o primeiro '!', O código é executado no segmento do usuário que fez um Async.Run.) "Vamos!" deixa para ir de um segmento enquanto a operação assíncrona está no mar, e depois pega um thread do ThreadPool quando a operação retorna. O (desempenho) vantagem é menos pressão contra o ThreadPool. (E, claro, a grande vantagem de usuário é o modelo de programação simples - um milhão de vezes melhor do que tudo o que BeginFoo / EndFoo / callback coisas que de outra forma escrita)

Veja também http://cs.hubfs.net/forums/thread/8262. aspx

Outras dicas

Eu estava escrevendo uma resposta, mas Brian chegou antes de mim. Concordo plenamente com ele.

Eu gostaria de acrescentar que, se você quiser paralelizar código síncrono, a ferramenta certa é PLINQ, não assíncrona fluxos de trabalho, como Don Syme explica .

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top