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

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

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


person Alex K    schedule 24.06.2012    source แหล่งที่มา
comment
อ่านคำถามนี้เพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีใช้ HttpClient อย่างถูกต้องและกำจัดทิ้ง: stackoverflow.com/questions/15705092/   -  person Mani Gandham    schedule 03.07.2016


คำตอบ (3)


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

CancelPendingRequests
DeleteAsync
GetAsync
GetByteArrayAsync
GetStreamAsync
GetStringAsync
PostAsync
PutAsync
SendAsync
PatchAsync
person Marcel N.    schedule 24.06.2012
comment
ใช่ ฉันไม่แน่ใจเกี่ยวกับอันนั้น เนื่องจากดูเหมือนว่าจะเป็นคำเตือนมาตรฐานสำหรับทุกสิ่งบน MSDN (และฉันจำได้ว่าอ่านบล็อก MSDN บางบล็อกเกี่ยวกับบางครั้งคำเตือนนั้นผิด เนื่องจากมันถูกนำไปใช้กับทุกสิ่งอย่างสุ่มสี่สุ่มห้า) - person Alex K; 24.06.2012
comment
@AlexK: ฉันคงไม่เชื่อสิ่งที่ฉันได้ยิน ดูอันนี้: msdn.microsoft.com/en-us/library /dd287191.aspx. โดยทั่วไปแล้วฉันจะเชื่อถือ MSDN - person Marcel N.; 24.06.2012
comment
บล็อกก็อยู่ใน MSDN เช่นกันซึ่งเป็นปริศนา :) ไม่ว่าอย่างไรก็ตาม ฉันคิดว่าฉันจะทำผิดพลาดโดยระมัดระวังและทำกลยุทธ์ตามคำขอของลูกค้า - person Alex K; 24.06.2012
comment
ในทางกลับกัน HttpClient มี CancelPendingRequests ซึ่งยกเลิกคำขอที่รอดำเนินการทั้งหมดบนอินสแตนซ์นี้ - ดูเหมือนว่าจะแนะนำว่าสามารถมีคำขอได้หลายรายการในเที่ยวบิน - person friism; 09.07.2012
comment
นี่เป็นสิ่งที่ผิด ในส่วนหมายเหตุของหน้า MSDN ที่คุณเชื่อมโยง จะมีข้อความว่า GetAsync, PostAsync ฯลฯ ทั้งหมดปลอดภัยสำหรับเธรด - person ischell; 04.01.2013
comment
@ischell: ฉันรับรองกับคุณได้ว่าย่อหน้าที่เป็นปัญหาไม่ได้อยู่ที่นั่นในขณะที่หารือเกี่ยวกับปัญหานี้ - person Marcel N.; 04.01.2013
comment
FYI ยังคงบอกว่าวิธีการอินสแตนซ์ไม่ปลอดภัยสำหรับเธรดที่ด้านล่างของหน้า MSDN - person Matt; 16.10.2013
comment
@Matt: มีอยู่เสมอและเป็นหมายเหตุทั่วไปเกี่ยวกับความปลอดภัยของเธรดสำหรับ .NET ทุกประเภท ดูส่วนหมายเหตุด้านบนในบทความ MSDN - person Marcel N.; 16.10.2013
comment
ดังนั้น Microsoft ได้ออกแบบ HttpClient ให้สามารถนำมาใช้ซ้ำได้ แต่คลาสนั้นมีข้อมูลอินสแตนซ์สำหรับส่วนหัว: client.DefaultRequestHeaders.Accept.Add(...); - person cwills; 11.06.2014
comment
ฉันไม่แน่ใจว่า HttpClient ปลอดภัยต่อเธรดหรือไม่ มี 2 ​​สถานการณ์ที่นี่: 1. การเรียก client.GetAsync() รอให้มันส่งคืนออบเจ็กต์งาน จากนั้นจึงเรียกอีกครั้ง (บนเธรดใดก็ได้) - ควรจะโอเค - การโทรของเราไม่พร้อมกัน HttpClient จัดการคำขอในเบื้องหลังและทำงานแต่ละงานให้เสร็จสิ้นเมื่อคำขอเสร็จสิ้น หรือ 2. การเรียก client.GetAsync() ซ้ำๆ บนหลายเธรดโดยไม่ต้องรอให้วัตถุงานถูกส่งคืนในแต่ละครั้ง นี่คือการทำงานพร้อมกันและฉันสงสัยว่าสิ่งนี้ได้รับการสนับสนุนทันที ไม่รับประกันวิธีการ Async เพื่อความปลอดภัยของเธรด (กรณีที่ #2) - person Alec Bryte; 02.06.2015
comment
ช้าแต่อยากแสดงความคิดเห็นใน @cwills DefaultRequestHeaders เป็นเพียงค่าเริ่มต้น หากคุณต้องการส่วนหัวที่แตกต่างกันตามคำขอ คุณสามารถสร้าง StringContent() ใหม่ ตั้งค่าส่วนหัวเพิ่มเติม จากนั้นใช้การโอเวอร์โหลดที่รับ URI และ HttpContent - person Ryan Anderson; 21.11.2017
comment
HttpClient ยังมีการเชื่อมต่อสูงสุดเริ่มต้นต่อเซิร์ฟเวอร์ (HttpClientHandler.MaxConnectionsPerServer) เพียง 2 ตรวจสอบให้แน่ใจว่าคุณเพิ่มสิ่งนั้น ไม่เช่นนั้นคำขอแบบมัลติเธรดของคุณจะถูกบล็อก - person PerpetualStudent; 15.06.2018
comment
นอกจากนี้ หากต้องการตั้งค่า Uri และส่วนหัวที่แตกต่างกันในคำขอแบบเธรด คุณสามารถใช้ HttpRequestMessage และส่งผ่านไปยัง SendAsync ได้ เป็นต้น - person PerpetualStudent; 15.06.2018
comment
ไม่มีใครรู้ว่ารูปแบบซิงเกิลตันสำหรับ HttpClient นี้ปลอดภัยหรือไม่ที่จะใช้ฝั่งเซิร์ฟเวอร์บนแอปพลิเคชันที่จะมีผู้ใช้หลายคน - person Chucky; 25.02.2019

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

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

person muruge    schedule 15.11.2012
comment
แล้วถ้าชื่อผู้ใช้และรหัสผ่านสามารถเปลี่ยนระหว่างเธรดได้ล่ะ? นั่นคือสิ่งที่ฉันไม่สามารถหาใครพูดถึงได้ - person Nicholas DiPiazza; 05.11.2016
comment
@NicholasDiPiazza: มันเปลี่ยนแปลงบ่อยแค่ไหน? หากมีคู่ผู้ใช้/รหัสผ่านที่ทราบ คุณสามารถสร้างกลุ่มของอินสแตนซ์ HttpClient ได้ - person Marcel N.; 23.06.2017
comment
ใช่นั่นคือสิ่งที่ฉันทำ - person Nicholas DiPiazza; 23.06.2017
comment
โปรดทราบว่าการใช้ HttpClient เดิมซ้ำกับคำขอทั้งหมดของคุณอาจส่งผลให้เกิดปัญหา DNS เก่า: github.com/dotnet /corefx/issues/11224. - person Ohad Schneider; 07.07.2017
comment
@OhadSchneider หากเชื่อว่าปัญหานั้น จำกัด อยู่ที่. net core คุณสามารถแก้ไขปัญหาด้วย .net 4 ได้โดยการฉีด HttpClientHandler แบบกำหนดเองลงในตัวสร้าง HttpClient จากนั้นตั้งค่า ConnectionLeaseTimeout อย่างไรก็ตาม หากไม่มีการส่งคำขอไปยังปลายทางเป็นเวลา 100 วินาที การเชื่อมต่อจะรีเฟรชเอง ป้องกันการแทนที่งาน SendAsync (คำขอ HttpRequestMessage, CancellationToken cancelToken) { var sp = ServicePointManager.FindServicePoint (request.RequestUri); sp.ConnectionLeaseTimeout = 100 * 1,000; } - person Timothy Gonzalez; 04.10.2017
comment
ประเด็นคืออะไร? HttpClient มีราคาแพงเป็นพิเศษที่คุณไม่ควรสร้างใหม่สำหรับแต่ละคำขอหรือไม่ - person xr280xr; 07.04.2021
comment
@ xr280xr คำตอบง่ายๆ: ใช่ การกำจัดมันจะทำให้ซ็อกเก็ต TCP ของคุณหมดลงอย่างรวดเร็วภายใต้การโหลด คำตอบยาวๆ: มันซับซ้อน และไม่มีใครรู้วิธีใช้งานที่ถูกต้องจริงๆ aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong stackoverflow.com/a/15708633/825588 https://www.nimaara.com/beware-of-the-net-httpclient/ docs.microsoft.com/en-us/azure/architecture/antipatterns/ - person Johann; 22.04.2021
comment
นอกจากนี้ stackoverflow.com/a/35045301/825588 และ stackoverflow.com/a/19003704/825588 - person Johann; 22.04.2021

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

สรุปโดยย่อ:

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