System.Net.Http.HttpClient y System.Net.Http.HttpClientHandler dans .NET Framework 4.5 mettent en œuvre IDisposable (via System.Net.Http.HttpMessageInvoker ).
El using
La documentation de la déclaration dit :
En règle générale, lorsque vous utilisez un objet IDisposable, vous devez le déclarer et l'instancier dans une instruction using. l'instancier dans une instruction using.
Cette réponse utilise ce modèle :
var baseAddress = new Uri("http://example.com");
var cookieContainer = new CookieContainer();
using (var handler = new HttpClientHandler() { CookieContainer = cookieContainer })
using (var client = new HttpClient(handler) { BaseAddress = baseAddress })
{
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("foo", "bar"),
new KeyValuePair<string, string>("baz", "bazinga"),
});
cookieContainer.Add(baseAddress, new Cookie("CookieName", "cookie_value"));
var result = client.PostAsync("/test", content).Result;
result.EnsureSuccessStatusCode();
}
Mais les exemples les plus visibles de Microsoft n'appellent pas à l'aide. Dispose()
soit explicitement, soit implicitement. Par exemple :
- El article de blog original annonçant la disparition de HttpClient.
- L'actuel Documentation MSDN pour HttpClient.
- BingTranslateSample
- GoogleMapsSample
- Banque mondialeEchantillon
Dans le annonce quelqu'un a demandé à l'employé de Microsoft :
Après avoir vérifié vos échantillons, j'ai vu que vous n'avez pas effectué l'action "dispose" sur l'instance HttpClient. sur l'instance HttpClient. J'ai utilisé toutes les instances de HttpClient avec l'instruction using dans mon application et j'ai pensé que c'était la bonne méthode puisque HttpClient implémente l'interface IDisposable. Suis-je sur la bon chemin ?
Sa réponse était :
En général, c'est correct, bien qu'il faille faire attention avec avec "using" et async, car ils ne se mélangent pas vraiment dans .Net 4. pouvez utiliser "await" dans une déclaration "using".
En fait, vous pouvez réutiliser le même HttpClient autant de fois que vous le souhaitez. généralement, vous ne les créerez pas et ne les jetterez pas tout le temps.
Le deuxième paragraphe est superflu pour cette question, qui ne concerne pas le nombre de fois que vous pouvez utiliser une instance de HttpClient, mais la question de savoir s'il est nécessaire de s'en débarrasser lorsque vous n'en avez plus besoin.
(Mise à jour : en fait, ce deuxième paragraphe est la clé de la réponse, comme indiqué ci-dessous par @DPeden).
Mes questions sont donc les suivantes :
-
Est-il nécessaire, compte tenu de l'implémentation actuelle (.NET Framework 4.5), d'appeler Dispose() sur les instances HttpClient et HttpClientHandler ? Clarification : par "nécessaire", je veux dire s'il y a des conséquences négatives à ne pas disposer, comme des risques de fuite de ressources ou de corruption de données.
-
Si ce n'est pas nécessaire, serait-ce de toute façon une "bonne pratique", puisqu'ils implémentent IDisposable ?
-
Si c'est nécessaire (ou recommandé), est-ce que ce code mentionné ci-dessus en le mettant en œuvre en toute sécurité (pour .NET Framework 4.5) ?
-
Si ces classes ne nécessitent pas d'appeler Dispose(), pourquoi ont-elles été implémentées comme IDisposable ?
-
S'ils l'exigent, ou s'il s'agit d'une pratique recommandée, les exemples de Microsoft sont-ils trompeurs ou dangereux ?
0 votes
"Si ce n'est pas absolument nécessaire..." - c'est jamais Il n'est pas "absolument nécessaire" de se débarrasser de tout ce qui est jetable. De la même manière qu'il n'est pas "absolument nécessaire" de jeter ses déchets de manière responsable si l'on se rend chez quelqu'un d'autre.
2 votes
@Damien_The_Unbeliever, merci pour vos commentaires. Avez-vous des suggestions sur la façon dont je pourrais clarifier la question ? Je veux savoir si cela peut conduire aux problèmes généralement associés à la non-élimination des ressources, tels que la fuite de ressources et la corruption de données.
10 votes
@Damien_The_Unbeliever : C'est faux. En particulier, les écrivains de flux doivent être disposés pour avoir un comportement correct.
0 votes
Je crois que je ne vois pas l'intérêt de la question. Vous savez qu'ils mettent en œuvre le modèle jetable. Vous êtes conscient de ce que vous (en tant que bon citoyen/consommateur) êtes censé faire avec un objet jetable lorsque vous n'en avez plus besoin. Vous êtes également conscient que le attente est qu'un de ces objets peut être utilisé pour plusieurs requêtes. Il est donc peu probable que vous voyiez des exemples qui se contentent d'en créer un, d'envoyer une seule requête, puis de s'en débarrasser immédiatement.
1 votes
@StephenCleary - à quels aspects pensez-vous ? Bien sûr, vous pouvez appeler
Flush
sur un après chaque écriture, et à part l'inconvénient de continuer à retenir les ressources sous-jacentes plus longtemps que nécessaire, qu'est-ce qui ne se produira pas qui est requis pour un "comportement correct" ?0 votes
@Damien_The_Unbeliever dans le code que j'écris habituellement, je crée une nouvelle instance de HttpClient lorsque j'ai besoin d'envoyer une nouvelle requête au lieu de conserver cette instance de client. Je pense que cela correspond bien à la nature sans état du protocole HTTP. Mais je n'avais pas l'habitude de me débarrasser de ces instances, et je viens de remarquer aujourd'hui qu'elles implémentent IDisposable. C'est pourquoi j'essaie de savoir si je suis censé les éliminer explicitement. J'espère que cela clarifie ma question.
0 votes
Il ne semble pas y avoir de réponse claire à cette question. Étant donné qu'il doit s'agir de l'une des classes .net les plus utilisées dans le monde moderne de l'Internet, je trouve assez étrange que MSDN n'ait pas clairement clarifié la manière dont elle doit être utilisée.
2 votes
C'est tout simplement faux : "En règle générale, lorsque vous utilisez un objet IDisposable, vous devez le déclarer et l'instancier dans une instruction using". Je lirais toujours la documentation sur la classe implémentant IDisposable avant de décider si je dois utiliser un using pour elle. En tant qu'auteur de bibliothèques où j'implémente IDisposable parce que j'ai besoin de libérer des ressources inchangées, je serais horrifié si les consommateurs créaient une instance disposée à chaque fois au lieu de réutiliser une instance existante. Cela ne veut pas dire qu'il ne faut pas disposer d'une instance éventuellement
1 votes
J'ai soumis un PR à Microsoft pour mettre à jour leur documentation : github.com/dotnet/docs/pull/2470
0 votes
Le modèle jetable est un apprentissage obligatoire pour la certification C# .net 4.5. Une certaine confusion réside dans la rétrocompatibilité avec .net 2.0 en utilisant trop idisposible (comme avec les flux de mémoire et IEnumerable). Vous devriez garantir que dispose est appelé immédiatement après avoir fini de l'utiliser pour tout ce qui enveloppe des " ressources externes ". Les fichiers en sont un bon exemple. Quand un httpClient (par question) lit un fichier, même si vous exécutez flush, un verrou persistant est maintenu. Sur votre système, GC le nettoiera rapidement. Sur un autre, qui sait ? Ou au fur et à mesure que votre environnement change. Un jour, il sera impossible d'écrire dessus.
0 votes
La nouvelle meilleure façon de gérer HttpClient et HttpClientHandler dans .Net Core 2.1 : HttpClientFactory . Résout une multitude de problèmes et d'embûches potentiels.
0 votes
Voici le post officiel de Microsoft sur la façon d'utiliser correctement HttpClient. docs.microsoft.com/fr/us/dotnet/architecture/microservices/