HttpClient - एक कार्य रद्द कर दिया गया था?


191

जब एक या दो कार्य होते हैं तो यह ठीक काम करता है लेकिन जब हम एक से अधिक कार्य सूचीबद्ध करते हैं तो एक त्रुटि "एक कार्य रद्द कर दिया गया" होता है।

यहां छवि विवरण दर्ज करें

List<Task> allTasks = new List<Task>();
allTasks.Add(....);
allTasks.Add(....);
Task.WaitAll(allTasks.ToArray(), configuration.CancellationToken);


private static Task<T> HttpClientSendAsync<T>(string url, object data, HttpMethod method, string contentType, CancellationToken token)
{
    HttpRequestMessage httpRequestMessage = new HttpRequestMessage(method, url);
    HttpClient httpClient = new HttpClient();
    httpClient.Timeout = new TimeSpan(Constants.TimeOut);

    if (data != null)
    {
        byte[] byteArray = Encoding.ASCII.GetBytes(Helper.ToJSON(data));
        MemoryStream memoryStream = new MemoryStream(byteArray);
        httpRequestMessage.Content = new StringContent(new StreamReader(memoryStream).ReadToEnd(), Encoding.UTF8, contentType);
    }

    return httpClient.SendAsync(httpRequestMessage).ContinueWith(task =>
    {
        var response = task.Result;
        return response.Content.ReadAsStringAsync().ContinueWith(stringTask =>
        {
            var json = stringTask.Result;
            return Helper.FromJSON<T>(json);
        });
    }).Unwrap();
}

इनर एक्सेप्शन को क्या कहते हैं?
रग्मट्विली

1
आप एक CancellationTokenपैरामीटर के रूप में क्यों लेते हैं और इसका उपयोग नहीं करते हैं?
जिम आहो

1
मेरे लिए इसका कारण HttpClientगलती से async Task<HttpResponseMessage> Method(){ using(var client = new HttpClient()) return client.GetAsync(request); }
निपटना

3
HttpClient@JobaDiniz (a using()) के साथ उपयोग करने वालों के लिए , कृपया बंद करें! कारण: aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong
फिलिप

जवाबों:


272

TaskCanceledExceptionफेंके जाने के 2 संभावित कारण हैं :

  1. कुछ कहा जाता है Cancel()पर CancellationTokenSourceकाम पूरा होने से पहले टोकन रद्द करने के साथ जुड़े।
  2. आपके द्वारा निर्दिष्ट समय के भीतर अनुरोध का समय समाप्त हो गया है, अर्थात पूरा नहीं हुआ है HttpClient.Timeout

मेरा अनुमान है कि यह एक टाइमआउट था। (यदि यह एक स्पष्ट रद्दीकरण था, तो आप शायद समझ गए होंगे।) आप अपवाद का निरीक्षण करके अधिक निश्चित हो सकते हैं:

try
{
    var response = task.Result;
}
catch (TaskCanceledException ex)
{
    // Check ex.CancellationToken.IsCancellationRequested here.
    // If false, it's pretty safe to assume it was a timeout.
}

3
तो एक संभव उपाय क्या है? मेरा भी वही मुद्दा है। stackoverflow.com/questions/36937328/…
डेवलपर

48
@ डिमी - यह बहुत पुराना है, लेकिन मैंने जो समाधान किया था वह टाइमआउट संपत्ति को एक बड़े मूल्य पर सेट करने के लिए था:httpClient.Timeout = TimeSpan.FromMinutes(30)
RQDQ

2
@RQDQ, आप आदमी, आदमी! कंस्ट्रक्टर का उपयोग नहीं करने से मेरे लिए समस्या हल हो गई। मेरे विशिष्ट मामले में, मुझे मिलीसेकंड में एक टाइमआउट चाहिए था। एक इलाज के TimeSpan.FromMilliseconds(Configuration.HttpTimeout)विपरीत के रूप में उपयोग करना new TimeSpan(Configuration.HttpTimeout)। धन्यवाद!
विक्टर

6
@RQDQ httpClient.Timeout = TimeSpan.FromMinutes(30)एक अच्छा तरीका नहीं है, क्योंकि यह उस विशेष धागे को 30 मिनट के लिए ब्लॉक कर देगा और HTTP एंडपॉइंट (जो कि आपका मुख्य कार्य है) को भी प्रभावित नहीं करेगा। इसके अलावा, यदि आपका कार्यक्रम 30 मिनट से पहले खत्म हो जाता है, तो आपका सामना होने की संभावना है ThreadAbortException। एक बेहतर तरीका यह पता लगाना होगा कि HTTP समापन बिंदु हिट क्यों नहीं हो रहा है, इसके लिए वीपीएन या कुछ प्रतिबंधित नेटवर्क एक्सेस की आवश्यकता हो सकती है।
अमित उपाध्याय

6
@AmitUpadhyay यदि कॉल awaitएड है, तो कोई थ्रेड ब्लॉक नहीं किया गया है। UI थ्रेड नहीं, थ्रेडपूल थ्रेड अन्य बैकग्राउंड थ्रेड, कोई नहीं।
टॉड मेनियर

20

मैं इस समस्या में भाग गया क्योंकि मेरा Main()तरीका लौटने से पहले कार्य पूरा होने की प्रतीक्षा नहीं कर Task<HttpResponseMessage> myTaskरहा था , इसलिए जब मेरे कंसोल प्रोग्राम से बाहर निकला तो रद्द किया जा रहा था।

समाधान ( इस उत्तर से ) myTask.GetAwaiter().GetResult()में कॉल करना था ।Main()


9

एक और संभावना यह है कि परिणाम ग्राहक की ओर से प्रतीक्षित नहीं है। यह तब हो सकता है यदि कॉल स्टैक पर कोई भी विधि कॉल पूरा होने के लिए प्रतीक्षा करने के लिए प्रतीक्षित कीवर्ड का उपयोग नहीं करती है।


8
var clientHttp = new HttpClient();
clientHttp.Timeout = TimeSpan.FromMinutes(30);

बड़े अनुरोध पर प्रतीक्षा करने के लिए उपरोक्त सबसे अच्छा तरीका है। आप 30 मिनट के बारे में उलझन में हैं; यह यादृच्छिक समय है और आप किसी भी समय दे सकते हैं जो आप चाहते हैं।

दूसरे शब्दों में, अनुरोध 30 मिनट से पहले परिणाम प्राप्त करने पर 30 मिनट तक इंतजार नहीं करेगा। 30 मिनट का मतलब है अनुरोध प्रसंस्करण समय 30 मिनट है। जब हमें त्रुटि हुई "टास्क रद्द कर दिया गया", या बड़े डेटा अनुरोध की आवश्यकताएं।


0

एक और कारण यह हो सकता है कि यदि आप सेवा (एपीआई) चला रहे हैं और सेवा में एक विराम बिंदु डाल रहे हैं (और आपका कोड कुछ विराम बिंदु पर अटका हुआ है (जैसे विजुअल स्टूडियो समाधान रनिंग के बजाय डिबगिंग दिखा रहा है )। और फिर क्लाइंट कोड से एपीआई को मारना। इसलिए यदि सर्विस कोड कुछ ब्रेकपॉइंट पर रुका हुआ है, तो आप वीएस में एफ 5 को हिट करें।


0

मेरी स्थिति में, नियंत्रक विधि को async नहीं बनाया गया था और नियंत्रक विधि के अंदर बुलाया विधि async थी।

इसलिए मुझे लगता है कि इन जैसे मुद्दों से बचने के लिए async / top शीर्ष स्तर तक सभी तरह की प्रतीक्षा करना महत्वपूर्ण है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.