7

मैंने अपने एपीआई कॉल के लिए FileResult : IHttpActionResult वेबपीआई रिटर्न प्रकार बनाया है। FileResult एक फ़ाइल को किसी अन्य यूआरएल से डाउनलोड करता है और फिर क्लाइंट को स्ट्रीम देता है।कथन का उपयोग करने में HttpClient कारण रद्द कर दिया गया है

शुरू में मेरी कोड के नीचे की तरह एक using बयान था:

public async Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken) 
{ 
    try 
    { 
     HttpResponseMessage response; 
     using (var httpClient = new HttpClient()) 
     { 

      response = new HttpResponseMessage(HttpStatusCode.OK) 
      { 
       Content = new System.Net.Http.StreamContent(
            await httpClient.GetStreamAsync(this.filePath)) 
      }; 
     } 
     return response; 
    } 
    catch (WebException exception) 
    {...} 
} 

हालांकि इस बीच-बीच में एक TaskCanceledException का कारण होगा। मुझे पता है कि अगर एटीक्रोनियस कॉल समाप्त हो जाने से पहले एचटीपी क्लाइंट का निपटारा किया जाता है तो कार्य का राज्य रद्द हो जाएगा। हालांकि, जब से मैं का उपयोग में Content = new System.Net.Http.StreamContent(await httpClient.GetStreamAsync(this.filePath)) का उपयोग करता हूं, तो एचटीपी क्लाइंट को कार्य पूरा करने के बीच में निपटने से रोकना चाहिए।

यह कार्य क्यों रद्द हो जाता है? यह समय सीमा के कारण नहीं है क्योंकि यह सबसे छोटे अनुरोधों पर हुआ है और हमेशा बड़े अनुरोधों पर नहीं होता है।

public async Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken) 
{ 
    try 
    { 
     HttpResponseMessage response; 
     var httpClient = new HttpClient(); 

     response = new HttpResponseMessage(HttpStatusCode.OK) 
     { 
      Content = new System.Net.Http.StreamContent(
           await httpClient.GetStreamAsync(this.filePath)) 
     }; 
     return response; 
    } 
    catch (WebException exception) 
    {...} 
} 

किसी भी विचार क्यों का उपयोग कर समस्या के कारण:

जब मैं using बयान कोड को ठीक से काम निकाल दिया?

+0

क्या आपने डीबगर का उपयोग करने का प्रयास किया है? इसे चरण-दर-चरण जांचना। – kevintjuh93

+0

हाँ मेरे पास है। यह वास्तव में मदद नहीं करता है क्योंकि अपवाद को यहां नहीं फेंक दिया गया है लेकिन एक पूरी तरह से अलग स्थान पर है। यह ओविन पाइपलाइन में होता है जिसका उपयोग मैं प्रमाणीकरण कर रहा हूं और यह अगले अनुरोध का इंतजार कर रहा है। – Rafi

+0

क्या 'टास्ककैंक्लेड एक्सेप्शन' में कोई आंतरिक अपवाद है? –

उत्तर

9

मुझे पता है कि अगर HttpClient से पहले एसिंक्रोनस कॉल समाप्त हो जाने निपटान किया जाता है टास्क के राज्य रद्द करने के लिए बदल जाएगा। हालांकि जब से मैं इसमें प्रतीक्षा करता हूं: सामग्री = नया सिस्टम.Net.Http.StreamContent (httpClient.GetStreamAsync (this.filePath) का इंतजार करें) जो HttpClient को कार्य पूर्ण होने के मध्य में डिस्पोजेड होने से रोकना चाहिए।

लेकिन यह कार्य क्या करता है? यह स्ट्रीम प्राप्त करता है। इसलिए, आपका कोड Stream के साथ समाप्त होता है जो HttpClient को बंद करते समय पूरी तरह से पढ़ा जा सकता है या नहीं।

HttpClient विशेष रूप से पुन: उपयोग (और एक साथ इस्तेमाल) के लिए डिज़ाइन किया गया है, तो मैं पूरी तरह से using को दूर करने और एक static वर्ग के सदस्य के लिए HttpClient घोषणा चलती सलाह देते हैं। लेकिन यदि आप ग्राहकों को बंद करना और फिर से खोलना चाहते हैं, तो आपको HttpClient को बंद करने से पहले पूरी तरह से स्मृति में स्ट्रीम को पढ़ने में सक्षम होना चाहिए।

4

मुझे कार्य रद्द अपवादों के साथ एक ही समस्या थी। आप AggregateException पकड़ने या अपने WebException के नीचे एक पकड़ सभी Exception ब्लॉक होने की कोशिश करते हैं, तो आप अच्छी तरह से है कि आप इसे प्रवेश करते हुए कहा "एक कार्य रद्द कर दिया गया"

मैं कुछ जांच किया था और पाया के साथ पकड़ने, एक अपवाद के साथ पा सकते हैं कि विभिन्न धागे में वर्णित AggregateException काफी भ्रामक है;

Setting HttpClient to a too short timeout crashes process

How can I tell when HttpClient has timed out?

Bug in httpclientgetasync should throw webexception not taskcanceledexception

मैं एक स्पष्ट टाइमआउट (जहां asyncTimeoutInMins app.config फ़ाइल से पढ़ा जाता है) स्थापित करने के लिए मेरे कोड को बदलने के समाप्त हो गया;

 string jsonResponse = string.Empty; 
     try 
     { 
      using (HttpClient httpClient = new HttpClient()) 
      { 
       httpClient.BaseAddress = new Uri(Properties.Settings.Default.MyWebService); 
       httpClient.DefaultRequestHeaders.Accept.Clear(); 
       httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 
       httpClient.Timeout = new TimeSpan(0, asyncTimeoutInMins, 0); 

       HttpResponseMessage response; 

       response = await httpClient.GetAsync("/myservice/resource"); 

       // Check the response StatusCode 
       if (response.IsSuccessStatusCode) 
       { 
        // Read the content of the response into a string 
        jsonResponse = await response.Content.ReadAsStringAsync(); 
       } 
       else if (response.StatusCode == HttpStatusCode.Forbidden) 
       { 
        jsonResponse = await response.Content.ReadAsStringAsync(); 

        Logger.Instance.Warning(new HttpRequestException(string.Format("The response StatusCode was {0} - {1}", response.StatusCode.ToString(), jsonResponse))); 

        Environment.Exit((int)ExitCodes.Unauthorised); 
       } 
       else 
       { 
        jsonResponse = await response.Content.ReadAsStringAsync(); 

        Logger.Instance.Warning(new HttpRequestException(string.Format("The response StatusCode was {0} - {1}", response.StatusCode.ToString(), jsonResponse))); 

        Environment.Exit((int)ExitCodes.ApplicationError); 
       } 
      } 

     } 
     catch (HttpRequestException reqEx) 
     { 
      Logger.Instance.Error(reqEx); 

      Console.WriteLine("HttpRequestException : {0}", reqEx.InnerException.Message); 

      Environment.Exit((int)ExitCodes.ApplicationError); 
     } 
     catch (Exception ex) 
     { 
      Logger.Instance.Error(ex); 

      throw; 
     } 

     return jsonResponse; 
+0

जैसा अपवाद के ऊपर टिप्पणी में उल्लिखित है वहां पर पकड़ा नहीं गया है लेकिन प्रमाणीकरण तर्क परत में। – Rafi

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

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