HttpClient ปลอดภัยที่จะใช้พร้อมกันไหม


151

ในตัวอย่างทั้งหมดที่ฉันสามารถหาได้จากการใช้งานHttpClientนั้นใช้สำหรับการโทรแบบครั้งเดียว แต่จะเกิดอะไรขึ้นถ้าฉันมีสถานการณ์ไคลเอนต์แบบถาวรซึ่งสามารถทำการร้องขอหลายอย่างพร้อมกันได้ โดยทั่วไปเป็นที่ปลอดภัยที่จะเรียกclient.PostAsyncใน 2 HttpClientหัวข้อในครั้งเดียวกับอินสแตนซ์เดียวกันของ

ฉันไม่ได้มองหาผลการทดลองที่นี่ ในฐานะที่เป็นตัวอย่างการทำงานอาจเป็นเรื่องบังเอิญ (และตัวอย่างที่ยังคงอยู่) และตัวอย่างที่ล้มเหลวอาจเป็นปัญหาการกำหนดค่าที่ผิดพลาด เป็นการดีที่ฉันกำลังมองหาคำตอบที่มีสิทธิ์สำหรับคำถามของการจัดการภาวะพร้อมกันใน HttpClient


2
อ่านคำถามนี้สำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีการใช้HttpClientและกำจัดอย่างถูกต้อง: stackoverflow.com/questions/15705092/…
Mani Gandham

คำตอบ:


152

อ้างอิงจาก MSDN , ตั้งแต่. NET 4.5 วิธีการอินสแตนซ์ต่อไปนี้เป็นเธรดที่ปลอดภัย (ขอบคุณ @ischell):

CancelPendingRequests
DeleteAsync
GetAsync
GetByteArrayAsync
GetStreamAsync
GetStringAsync
PostAsync
PutAsync
SendAsync

3
ใช่ฉันไม่แน่ใจเกี่ยวกับสิ่งนั้นเนื่องจากดูเหมือนจะเป็นคำเตือนมาตรฐานในทุกสิ่งบน MSDN (และฉันจำได้ว่าอ่านบล็อก MSDN บางรายการเกี่ยวกับวิธีที่คำเตือนนั้นผิด
Alex K

3
นี่เป็นสิ่งที่ผิด ในส่วนข้อสังเกตของหน้า MSDN ที่คุณเชื่อมโยงจะระบุว่า GetAsync, PostAsync และอื่น ๆ ทั้งหมดเป็นเธรดที่ปลอดภัย
ischell

4
@ischell: ฉันรับรองได้ว่าย่อหน้าที่เป็นปัญหาไม่ได้อยู่ที่ตอนที่มีการพูดคุยกัน
Marcel N.

7
ดังนั้น Microsoft ได้ออกแบบ HttpClient ให้สามารถใช้ซ้ำได้ แต่คลาสนั้นมีข้อมูลอินสแตนซ์สำหรับส่วนหัว: client.DefaultRequestHeaders.Accept.Add (... );
cwills

8
ช่วงปลายปี แต่ฉันต้องการแสดงความคิดเห็นใน @cwills DefaultRequestHeaders เป็นเพียงค่าเริ่มต้น หากคุณต้องการส่วนหัวที่แตกต่างกันตามคำขอต่อคุณสามารถสร้าง StringContent () ใหม่ตั้งค่าส่วนหัวเพิ่มเติมจากนั้นใช้โอเวอร์โหลดที่ใช้ URI และ HttpContent
Ryan Anderson

92

นี่คืออีกบทความจาก Henrik F. Nielsen เกี่ยวกับ HttpClient ที่เขาพูดว่า:

" ค่าเริ่มต้นของ HttpClient เป็นวิธีที่ง่ายที่สุดที่คุณสามารถเริ่มส่งคำขอได้HttpClient หนึ่งตัวสามารถใช้ส่งคำขอ HTTP ได้มากเท่าที่คุณต้องการในเวลาเดียวกันดังนั้นในหลาย ๆ สถานการณ์คุณสามารถสร้าง HttpClient เพียงอันเดียวแล้วใช้มันสำหรับคำขอของคุณทั้งหมด . "


13
จะเกิดอะไรขึ้นถ้าชื่อผู้ใช้และรหัสผ่านสามารถเปลี่ยนระหว่างเธรดได้? นั่นคือสิ่งที่ฉันไม่สามารถหาใครพูดถึง
Nicholas DiP Piazza

1
@NicholasDiP Piazza: เปลี่ยนบ่อยแค่ไหน? หากมีคู่ของผู้ใช้ / รหัสผ่านที่รู้จักกันดีคุณสามารถสร้างกลุ่ม HttpClient ได้
Marcel N.

ใช่นั่นคือสิ่งที่ฉันลงเอยทำ
นิโคลัส DiP Piazza

2
โปรดทราบว่าการนำเดียวกัน HttpClient สำหรับการร้องขอของคุณอาจทำให้เกิดปัญหา DNS เก่า: github.com/dotnet/corefx/issues/11224
Ohad Schneider

1
@OhadSchneider หากเชื่อว่าปัญหานั้น จำกัด อยู่ที่. net core คุณสามารถแก้ไขปัญหาด้วย. net 4 โดยการฉีด HttpClientHandler แบบกำหนดเองลงในตัวสร้าง HttpClient จากนั้นตั้งค่า "ConnectionLeaseTimeout" อย่างไรก็ตามหากไม่มีการร้องขอใด ๆ ที่ถูกส่งไปยังจุดปลายเป็นเวลา 100 วินาทีการเชื่อมต่อจะรีเฟรชด้วยตัวเอง การป้องกันการแทนที่งาน <HttpResponseMessage> SendAsync (การร้องขอ HttpRequestMessage, CancellationToken การยกเลิก Token) {var sp = ServicePointManager.FindServicePoint (request.RequestUri); sp.ConnectionLeaseTimeout = 100 * 1,000; }
Timothy Gonzalez

17

พบหนึ่งโพสต์ฟอรัม MSDNโดย Henrik F. Nielsen (หนึ่งในสถาปนิกหลักของ HttpClient)

สรุปด่วน:

  • หากคุณมีคำขอที่เกี่ยวข้อง (หรือจะไม่เหยียบย่ำกัน) การใช้ HttpClient เดียวกันก็สมเหตุสมผลดี
  • ใน genral ฉันขอแนะนำให้ใช้อินสแตนซ์ HttpClient ให้มากที่สุด
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.