7

हम एचटीपी क्लाइंट के लिए एक रैपर बना रहे हैं। चूंकि हम https://github.com/mspnp/performance-optimization से प्रदर्शन अनुकूलन मार्गदर्शन का पालन करने जा रहे हैं। हम एंटी-पैटर्न से बचना चाहते हैं - उस दस्तावेज़ में उल्लिखित अनुचित तत्कालता। मैंने स्थिर एचटीपी क्लाइंट का उपयोग करने के लिए अपनी टीम को यह मार्गदर्शन दिया। मुझे मिली फीडबैक थ्रेड-सुरक्षा पर है। प्रत्येक अनुरोध में एक शीर्षलेख होता है जिसमें उपयोगकर्ता दावा होता है। चूंकि मेरे पास स्थिर एचटीपी क्लाइंट है, क्या यह थ्रेड-सुरक्षित होगा? अगर हमारे पास एक ही समय में कोड (उदाहरण के लिए जीईटी) को मारने के कई अनुरोध हैं, तो क्या यह हेडर सेट करने के लिए दौड़ की स्थिति होगी? हमारे पास नीचे के रूप में कार्यान्वयन है।एएसपीनेट पर सुरक्षित स्टेटिक एचटीपी क्लाइंट थ्रेड HttpRequest

public class HttpClientHelper{ 
private static readonly HttpClient _HttpClient; 
static HttpClientHelper() { 
     HttpClient = new HttpClient(); 
     HttpClient.Timeout = TimeSpan.FromMinutes(SOME_CONFIG_VALUE); 
} 

public async Task<HttpResponseMessage> CallHttpClientPostAsync(string requestUri, HttpContent requestBody) 
{ 
    AddHttpRequestHeader(httpClient); 
    var response = await httpClient.PostAsync(requestUri, requestBody); //Potential thread synchronization issue??? 
    return response; 
} 

public HttpResponseMessage CallHttpClientGet(string requestUri) 
{ 
    AddHttpRequestHeader(httpClient); 
    var response = httpClient.GetAsync(requestUri).Result; //Potential thread synchronization issue??? 
    return response; 
} 

private void AddHttpRequestHeader(HttpClient client) 
{ 
    string HeaderName = "CorrelationId"; 
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(Properties.Settings.Default.HttpClientAuthHeaderScheme, GetTokenFromClaims()); //Race condition??? 
    if (client.DefaultRequestHeaders.Contains(HeaderName)) 
     client.DefaultRequestHeaders.Remove(HeaderName); 
    client.DefaultRequestHeaders.Add(HeaderName, Trace.CorrelationManager.ActivityId.ToString()); 
} 

}

+1

कोई कारण नहीं है कि 'CallHttpClientGet' async नहीं है? 'रेसल्ट' को कॉल करके आप थ्रेड को अवरुद्ध कर रहे हैं और संभावित डेडलॉक्स को आमंत्रित कर रहे हैं। –

उत्तर

10

आपकी टीम सही है, तो यह सुरक्षित धागा से दूर है। इस परिदृश्य पर विचार करें:

  • थ्रेड एक सेट सहसंबंध "foo" के लिए शीर्षलेख।
  • थ्रेड बी "बार" को सहसंबंध Id शीर्षलेख सेट करता है।
  • थ्रेड ए अनुरोध भेजता है, जिसमें थ्रेड बी के सहसंबंध आईडी शामिल हैं। अपने CallXXX तरीकों नई HttpRequestMessage वस्तुओं को बनाने के लिए है, और उन पर हैडर निर्धारित करते हैं, और HttpClient.SendAsync का उपयोग कॉल करने के लिए

एक बेहतर दृष्टिकोण होगा।

ध्यान रखें कि HttpClient उदाहरणों का पुन: उपयोग करना केवल फायदेमंद है यदि आप एक ही मेजबान को एकाधिक कॉल कर रहे हैं।

+0

"ध्यान रखें कि HttpClient उदाहरणों का पुन: उपयोग करना केवल फायदेमंद है यदि आप एक ही मेजबान को एकाधिक कॉल कर रहे हैं" - क्या आपके पास इसका संदर्भ है? –

+2

@ ओहडस्चनेडर यह एक उदाहरण का उपयोग करने के लिए [डेरिल मिलर की सलाह] (https://stackoverflow.com/a/22561368/62600) पर आधारित है "प्रत्येक विशिष्ट एपीआई के लिए जो आप कनेक्ट करते हैं"। कारण प्रदर्शन लाभ (नया कनेक्शन खोलने के लिए नहीं, आदि) केवल प्रति मेजबान प्रासंगिक हैं, जैसे कि DefatultHeaders जैसे कुछ HttpClient गुण हैं। हालांकि, अब-प्रसिद्ध [सॉकेट समस्या] (https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/) मेरी सलाह को थोड़ा बदल सकता है। क्या विंडोज एक अलग मेजबान के साथ उपयोग के लिए TIME_WAIT में सॉकेट पुनः प्राप्त कर सकता है? मुझे यकीन नहीं है। मैंने उस लेख पर सवाल पोस्ट किया। –

संबंधित मुद्दे