Là httpClient an toàn để sử dụng đồng thời?


151

Trong tất cả các ví dụ tôi có thể tìm thấy các cách sử dụng HttpClient, nó được sử dụng cho một lần gọi. Nhưng điều gì sẽ xảy ra nếu tôi có một tình huống khách hàng liên tục, trong đó một số yêu cầu có thể được thực hiện đồng thời? Về cơ bản, có an toàn không khi gọi client.PostAsync2 luồng cùng một lúc so với cùng một trường hợp HttpClient.

Tôi không thực sự tìm kiếm kết quả thử nghiệm ở đây. Như một ví dụ hoạt động có thể chỉ đơn giản là một con sán (và một ví dụ dai dẳng ở đó), và một ví dụ thất bại có thể là một vấn đề cấu hình sai. Lý tưởng nhất là tôi đang tìm kiếm một số câu trả lời có thẩm quyền cho câu hỏi về xử lý đồng thời trong HttpClient.


2
Cũng đọc câu hỏi này để biết thêm thông tin về cách sử dụng HttpClientvà vứt bỏ nó đúng cách : stackoverflow.com/questions/15705092/ chủ
Mani Gandham

Câu trả lời:


152

Theo MSDN , kể từ .NET 4.5 Các phương thức cá thể sau đây là luồng an toàn (cảm ơn @ischell):

CancelPendingRequests
DeleteAsync
GetAsync
GetByteArrayAsync
GetStreamAsync
GetStringAsync
PostAsync
PutAsync
SendAsync

3
Vâng, tôi không chắc về điều đó, vì nó dường như là một cảnh báo tiêu chuẩn cho mọi thứ trên MSDN (và tôi nhớ đã đọc một số blog MSDN về việc đôi khi cảnh báo đó sai, vì nó được áp dụng một cách mù quáng cho mọi thứ).
Alex K

3
Cái này sai; trong phần nhận xét của trang MSDN mà bạn đã liên kết, nó nói rằng GetAsync, PostAsync, v.v ... đều an toàn cho chủ đề.
ischell

4
@ischell: Tôi có thể đảm bảo với bạn rằng đoạn văn được đề cập không có tại thời điểm vấn đề này được thảo luận.
Marcel N.

7
Vì vậy, Microsoft đã thiết kế HTTPClient để có thể sử dụng lại nhưng sau đó lớp có dữ liệu cá thể cho các tiêu đề: client.DefaultRequestHeaders.Accept.Add (...);
cwills

8
Cuối cùng, nhưng tôi muốn bình luận về @cwills. DefaultRequestHeaders chỉ có vậy, mặc định. Nếu bạn muốn các tiêu đề khác nhau trên cơ sở theo yêu cầu, bạn có thể tạo StringContent () mới, đặt các tiêu đề bổ sung trên đó, sau đó sử dụng quá tải có URI và HttpContent.
Ryan Anderson

92

Đây là một bài viết khác của Henrik F. Nielsen về HttpClient, nơi ông nói:

" HTTPClient mặc định là cách đơn giản nhất để bạn có thể bắt đầu gửi yêu cầu. Một httpClient có thể được sử dụng để gửi nhiều yêu cầu HTTP như bạn muốn đồng thời , trong nhiều trường hợp, bạn chỉ có thể tạo một httpClient và sau đó sử dụng cho tất cả các yêu cầu của mình . "


13
Điều gì về nếu tên người dùng và mật khẩu có thể thay đổi giữa các chủ đề? đó là những gì tôi dường như không thể tìm thấy bất cứ ai nói về
Nicholas DiP Square

1
@NicholasDiP Square: nó có thường xuyên thay đổi không? Nếu có một tập hợp các cặp người dùng / mật khẩu đã biết thì bạn có thể tạo một nhóm các trường hợp httpClient.
Marcel N.

vâng đó là những gì tôi đã làm
Nicholas DiP Square

2
Lưu ý rằng việc sử dụng lại cùng một httpClient cho tất cả các yêu cầu của bạn có thể dẫn đến các sự cố DNS cũ: github.com/dotnet/corefx/issues/11224 .
Ohad Schneider

1
@OhadSchneider Nếu tin rằng vấn đề đó bị giới hạn ở lõi .net. Bạn có thể khắc phục sự cố với .net 4 bằng cách đưa một httpClientHandler tùy chỉnh vào hàm tạo HTTPClient sau đó đặt "ConnectionLeaseTimeout". Tuy nhiên, nếu không có yêu cầu nào được gửi đến điểm cuối trong 100 giây, kết nối sẽ tự làm mới. Nhiệm vụ ghi đè được bảo vệ <HttpResponseMessage> SendAsync (yêu cầu httpRequestMessage, CancellingToken CancellingToken) {var sp = ServicePointManager.FindServicePoint (request.RequestUri); sp.ConnectionLeaseTimeout = 100 * 1000; }
Timothy Gonzalez

17

Tìm thấy một bài đăng trên diễn đàn MSDN của Henrik F. Nielsen (một trong những kiến ​​trúc sư chính của httpClient).

Tóm tắt nhanh:

  • Nếu bạn có các yêu cầu có liên quan (hoặc sẽ không thực hiện từng bước) thì việc sử dụng cùng một httpClient có ý nghĩa rất lớn.
  • Trong thể loại, tôi khuyên bạn nên sử dụng lại các trường hợp httpClient càng nhiều càng tốt.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.