如何从F#使用HttpClient?
我是F#新手,从C#开发人员的角度理解F#中的异步。假设用C#编写以下代码片段:如何从F#使用HttpClient?,f#,task-parallel-library,async-await,dotnet-httpclient,c#-to-f#,F#,Task Parallel Library,Async Await,Dotnet Httpclient,C# To F#,我是F#新手,从C#开发人员的角度理解F#中的异步。假设用C#编写以下代码片段: var-httpClient=new-httpClient(); var response=wait-httpClient.GetAsync(url); response.EnsureSuccessStatusCode(); string content=wait response.content.ReadAsStringAsync(); 如何在F#?中编写相同的代码您可以使用async: let readStr
var-httpClient=new-httpClient();
var response=wait-httpClient.GetAsync(url);
response.EnsureSuccessStatusCode();
string content=wait response.content.ReadAsStringAsync();
如何在F#?中编写相同的代码您可以使用
async
:
let readString (url: Uri) = async {
let httpClient = new HttpClient();
let! response = httpClient.GetAsync(url) |> Async.AwaitTask
response.EnsureSuccessStatusCode() |> ignore
return! response.Content.ReadAsStringAsync() |> Async.AwaitTask
}
下面是一个函数,它应该完成您想要的功能(请注意,为了使用let!语法,您必须将代码包装在异步计算表达式中):
如果您使用F#中的
HttpClient
,您至少需要阅读并了解中的已建立模式
[见评论]TL;博士正如@pimbrouwers所指出的,应该注意的是,您不必再使用它——在您的上下文中对自己的助手集进行细分和/或改进可以使您获得更合适的抽象(并在学习过程中为您带来好处)
说到这一点:在F#中,将很少使用和/或过于特定的助手放在非中心位置被认为是惯用做法。只要我的两分钱。但我的理解是,在使用
EnsureSuccessStatusCode()
时,我们应该处理HttpRequestException
下面是模块包装HttpClient
的开始,该模块将URL响应缓冲到字符串中,并安全地包装到结果中,以提高容错性
module Http =
open System
open System.Net.Http
let getStringAsync url =
async {
let httpClient = new HttpClient()
// This can be easily be made into a HttpClientFactory.Create() call
// if you're using >= netcore2.1
try
use! resp = httpClient.GetAsync(Uri(url), HttpCompletionOption.ResponseHeadersRead) |> Async.AwaitTask
resp.EnsureSuccessStatusCode |> ignore
let! str = resp.Content.ReadAsStringAsync() |> Async.AwaitTask
return Ok str
with
| :? HttpRequestException as ex -> return ex.Message |> Error
}
只需使用FSharp.Control.fusiontask
,就可以获得清晰的语法,而不必像这样使用|>Async.AwaitTask
let httpClient = new System.Net.Http.HttpClient ()
let getAsync (url:string) =
async {
let! response = httpClient.GetAsync url
response.EnsureSuccessStatusCode () |> ignore
let! content = response.Content.ReadAsStringAsync ()
return content
}
前两个不应该让
s成为使用
s吗?(httpClient&响应为IDisposable)可能没有,httpClient
并非故意不尊重。但我发现答案是,有人直接去图书馆是一种逃避。当然,你最终可能会不可避免地使用它。但在我看来,你应该先亲自去那里。否则,我们最终会遇到一群程序员,他们已经远离他们真正想要做的事情,他们只能使用外部库来完成他们的工作。ADO.NET就是一个很好的例子。我所做的.NET开发人员中有多少人对代理SqlConnection
和执行SqlCommand
一无所知,你会感到震惊。关键是,你自己先试试。犯错误把事情搞砸了(我知道我总是这样)。但实际上在这个过程中我学到了一些东西;今天我不会写同样的答案。然而,我的观点是,在没有意识到一个广泛使用的库的情况下,不要为HttpClient
编写F#wrapping,例如,为相同的概念使用相同的命名等。将进行编辑以反映这一点。
let httpClient = new System.Net.Http.HttpClient ()
let getAsync (url:string) =
async {
let! response = httpClient.GetAsync url
response.EnsureSuccessStatusCode () |> ignore
let! content = response.Content.ReadAsStringAsync ()
return content
}