为什么 Async.Sequential 没有按预期工作(但在 FSI 中工作)?
Why Async.Sequential doesn't work as expected (but works in FSI)?
open System
open System.Net
let fetchUrlAsync url =
async {
Console.WriteLine(sprintf "Fetch <%s>" url)
let req = WebRequest.Create(Uri(url))
use! resp = req.AsyncGetResponse()
use stream = resp.GetResponseStream()
use reader = new IO.StreamReader(stream)
let html = reader.ReadToEnd()
Console.WriteLine(sprintf "finished downloading %s. Length = %i" url html.Length)
}
[<EntryPoint>]
let main argv =
["http://bing.com"; "http://ya.ru"; "http://google.com"]
|> List.map fetchUrlAsync
|> Async.Sequential
|> Async.Ignore
|> Async.RunSynchronously
输出:
Fetch <http://bing.com>
Fetch <http://ya.ru>
Fetch <http://google.com>
finished downloading http://google.com. Length = 50592
finished downloading http://ya.ru. Length = 20541
finished downloading http://bing.com. Length = 81386
我不期望这样的输出(但也许我的期望有误)。但是,如果我 运行 在 F# interactive 中使用相同的代码,则输出是(如我所料):
Fetch <http://bing.com>
finished downloading http://bing.com. Length = 81386
Fetch <http://ya.ru>
finished downloading http://ya.ru. Length = 20544
Fetch <http://google.com>
finished downloading http://google.com. Length = 50561
为什么 运行从 Rider(控制台应用程序)和 F# Interactive 运行 时代码的行为不同?如果第一个输出是正确的,那么 Async.Sequential 和 Async.Parallel 有什么区别?如果第一个输出不正确,那么如何解决?
目前,Async.Sequential
仅实现为:
static member Sequential computations =
Async.Parallel(computations, maxDegreeOfParallelism=1)
虽然 the RFC allows this,但预计会 运行 顺序。
已经 discovered to be a bug. And it has been fixed by #7596。
该修复程序现在仅在 VS 上发布。但它还没有在主线 FSharp.Core
nuget 提要中。
The only way to get the fix currently is through VS2019 16.4 FSI.
这就是为什么您会看到它在 FSI 中可以正常工作,但在您编译的应用程序中却不能。
解决方案
观看#7956,等待发货。
open System
open System.Net
let fetchUrlAsync url =
async {
Console.WriteLine(sprintf "Fetch <%s>" url)
let req = WebRequest.Create(Uri(url))
use! resp = req.AsyncGetResponse()
use stream = resp.GetResponseStream()
use reader = new IO.StreamReader(stream)
let html = reader.ReadToEnd()
Console.WriteLine(sprintf "finished downloading %s. Length = %i" url html.Length)
}
[<EntryPoint>]
let main argv =
["http://bing.com"; "http://ya.ru"; "http://google.com"]
|> List.map fetchUrlAsync
|> Async.Sequential
|> Async.Ignore
|> Async.RunSynchronously
输出:
Fetch <http://bing.com>
Fetch <http://ya.ru>
Fetch <http://google.com>
finished downloading http://google.com. Length = 50592
finished downloading http://ya.ru. Length = 20541
finished downloading http://bing.com. Length = 81386
我不期望这样的输出(但也许我的期望有误)。但是,如果我 运行 在 F# interactive 中使用相同的代码,则输出是(如我所料):
Fetch <http://bing.com>
finished downloading http://bing.com. Length = 81386
Fetch <http://ya.ru>
finished downloading http://ya.ru. Length = 20544
Fetch <http://google.com>
finished downloading http://google.com. Length = 50561
为什么 运行从 Rider(控制台应用程序)和 F# Interactive 运行 时代码的行为不同?如果第一个输出是正确的,那么 Async.Sequential 和 Async.Parallel 有什么区别?如果第一个输出不正确,那么如何解决?
目前,Async.Sequential
仅实现为:
static member Sequential computations =
Async.Parallel(computations, maxDegreeOfParallelism=1)
虽然 the RFC allows this,但预计会 运行 顺序。 已经 discovered to be a bug. And it has been fixed by #7596。
该修复程序现在仅在 VS 上发布。但它还没有在主线 FSharp.Core
nuget 提要中。
The only way to get the fix currently is through VS2019 16.4 FSI.
这就是为什么您会看到它在 FSI 中可以正常工作,但在您编译的应用程序中却不能。
解决方案
观看#7956,等待发货。