Apakah HttpClient aman digunakan secara bersamaan?

Dalam semua contoh yang saya temukan tentang penggunaan HttpClient, ini digunakan untuk panggilan satu kali. Namun bagaimana jika saya memiliki situasi klien yang persisten, dimana beberapa permintaan dapat dibuat secara bersamaan? Pada dasarnya, apakah aman untuk memanggil client.PostAsync pada 2 thread sekaligus terhadap instance HttpClient yang sama.

Saya tidak benar-benar mencari hasil eksperimen di sini. Contoh yang berfungsi bisa jadi hanya sebuah kebetulan (dan terus-menerus terjadi), dan contoh yang gagal bisa jadi merupakan masalah kesalahan konfigurasi. Idealnya saya mencari jawaban resmi untuk pertanyaan tentang penanganan konkurensi di HttpClient.


person Alex K    schedule 24.06.2012    source sumber
comment
Baca juga pertanyaan ini untuk info lebih lanjut tentang cara menggunakan HttpClient dengan benar dan membuangnya: stackoverflow.com/questions/15705092/   -  person Mani Gandham    schedule 03.07.2016


Jawaban (3)


Menurut Microsoft Docs, sejak .NET 4.5 Metode instance berikut aman untuk thread (terima kasih @ischell):

CancelPendingRequests
DeleteAsync
GetAsync
GetByteArrayAsync
GetStreamAsync
GetStringAsync
PostAsync
PutAsync
SendAsync
PatchAsync
person Marcel N.    schedule 24.06.2012
comment
Ya, saya tidak yakin tentang yang satu itu, karena tampaknya merupakan peringatan standar pada semua yang ada di MSDN (dan saya ingat membaca beberapa blog MSDN tentang bagaimana kadang-kadang peringatan itu salah, karena diterapkan secara membabi buta pada semuanya). - person Alex K; 24.06.2012
comment
@AlexK: Ya, saya tidak akan percaya apa pun yang saya dengar. Lihatlah yang ini: msdn.microsoft.com/en-us/library /dd287191.aspx. Jadi, saya biasanya mempercayai MSDN. - person Marcel N.; 24.06.2012
comment
Yah, blognya juga ada di MSDN, sebuah teka-teki :) Bagaimanapun, saya kira saya akan berhati-hati, dan melakukan strategi klien per permintaan. - person Alex K; 24.06.2012
comment
Di sisi lain, HttpClient memiliki CancelPendingRequests yang Membatalkan semua permintaan yang tertunda pada instance ini. - yang sepertinya menunjukkan bahwa ia dapat memiliki banyak permintaan dalam penerbangan. - person friism; 09.07.2012
comment
Ini salah; di bagian komentar pada halaman MSDN yang Anda tautkan, dikatakan bahwa GetAsync, PostAsync, dll. semuanya aman untuk thread. - person ischell; 04.01.2013
comment
@ischell: Saya dapat meyakinkan Anda bahwa paragraf yang dimaksud tidak ada pada saat masalah ini dibahas. - person Marcel N.; 04.01.2013
comment
FYI masih mengatakan metode instance tidak aman untuk thread di bagian bawah halaman MSDN. - person Matt; 16.10.2013
comment
@Matt: Itu selalu ada dan merupakan catatan umum tentang keamanan thread untuk semua tipe .NET. Lihat bagian Keterangan di atas dalam artikel MSDN. - person Marcel N.; 16.10.2013
comment
Jadi Microsoft telah merancang HttpClient agar dapat digunakan kembali tetapi kemudian kelas tersebut memiliki data instance untuk header: client.DefaultRequestHeaders.Accept.Add(...); - person cwills; 11.06.2014
comment
Saya tidak yakin apakah HttpClient aman untuk thread. Ada 2 skenario di sini: 1. Memanggil client.GetAsync(), menunggunya mengembalikan objek Task, lalu memanggilnya lagi (di thread mana pun) - seharusnya baik-baik saja - tidak ada konkurensi dengan panggilan kita. HttpClient menangani permintaan di latar belakang dan menyelesaikan setiap tugas setelah permintaan selesai, atau 2. Memanggil client.GetAsync() berulang kali di beberapa thread tanpa menunggu objek Task dikembalikan setiap saat. Ini adalah konkurensi dan saya ragu ini didukung secara langsung. Metode async tidak dijamin memberikan keamanan thread (kasus #2). - person Alec Bryte; 02.06.2015
comment
Terlambat, tapi saya ingin mengomentari @cwills. DefaultRequestHeaders hanya itu, default. Jika Anda menginginkan header yang berbeda berdasarkan permintaan, Anda dapat membuat StringContent() baru, menyetel header tambahan, lalu menggunakan kelebihan yang menggunakan URI dan HttpContent. - person Ryan Anderson; 21.11.2017
comment
HttpClient juga memiliki koneksi maksimum default per server (HttpClientHandler.MaxConnectionsPerServer) hanya 2. Pastikan Anda meningkatkannya, atau permintaan multi-utas Anda akan diblokir. - person PerpetualStudent; 15.06.2018
comment
Selain itu, untuk menyetel Uri dan header yang berbeda pada permintaan berulir, Anda dapat menggunakan HttpRequestMessage dan meneruskannya ke SendAsync misalnya. - person PerpetualStudent; 15.06.2018
comment
Adakah yang tahu jika pola tunggal untuk HttpClient ini aman digunakan di sisi server pada aplikasi yang akan memiliki banyak pengguna? - person Chucky; 25.02.2019

Berikut artikel lainnya dari Henrik F. Nielsen tentang HttpClient di mana dia berkata:

"HttpClient default adalah cara paling sederhana untuk mulai mengirim permintaan. Satu HttpClient dapat digunakan untuk mengirim permintaan HTTP sebanyak yang Anda inginkan secara bersamaan sehingga dalam banyak skenario Anda cukup membuat satu HttpClient lalu gunakan itu untuk semua permintaan Anda."

person muruge    schedule 15.11.2012
comment
Bagaimana jika nama pengguna dan kata sandi dapat diubah antar thread? itulah yang sepertinya tidak dapat saya temukan orang bicarakan - person Nicholas DiPiazza; 05.11.2016
comment
@NicholasDiPiazza: seberapa sering berubah? Jika ada kumpulan pasangan pengguna/kata sandi yang diketahui maka Anda dapat membuat kumpulan instance HttpClient. - person Marcel N.; 23.06.2017
comment
ya itulah yang akhirnya saya lakukan - person Nicholas DiPiazza; 23.06.2017
comment
Perhatikan bahwa menggunakan kembali HttpClient yang sama untuk semua permintaan Anda mungkin mengakibatkan masalah DNS basi: github.com/dotnet /corefx/issues/11224. - person Ohad Schneider; 07.07.2017
comment
@OhadSchneider Jika yakin bahwa masalah ini terbatas pada .net core. Anda dapat memperbaiki masalah dengan .net 4 dengan memasukkan HttpClientHandler khusus ke dalam konstruktor HttpClient lalu mengatur ConnectionLeaseTimeout. Namun, jika tidak ada permintaan yang dikirim ke titik akhir selama 100 detik, koneksi akan disegarkan dengan sendirinya. penggantian yang dilindungi Tugas‹HttpResponseMessage› SendAsync(permintaan HttpRequestMessage,CancellationToken cancellationToken) { var sp = ServicePointManager.FindServicePoint(request.RequestUri); sp.ConnectionLeaseTimeout = 100 * 1000; } - person Timothy Gonzalez; 04.10.2017
comment
Apa gunanya? Apakah HttpClient sangat mahal sehingga Anda tidak perlu membuat yang baru untuk setiap permintaan? - person xr280xr; 07.04.2021
comment
@xr280xr jawaban sederhana: ya, membuangnya akan cepat menghabiskan soket TCP Anda saat dimuat. Jawaban panjangnya: ini rumit, dan tidak ada yang tahu cara yang benar untuk menggunakannya. https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/ stackoverflow.com/a/15708633/825588 https://www.nimaara.com/waspadalah-of-the-net-httpclient/ docs.microsoft.com/en-us/azure/architecture/antipatterns/ - person Johann; 22.04.2021
comment

Ditemukan satu postingan forum MSDN oleh Henrik F. Nielsen (salah satu Arsitek utama HttpClient).

Ringkasan singkat:

  • #P3#
  • #P4#
person Alex K    schedule 25.06.2012