এইচটিপিপিলেট - একটি কাজ বাতিল করা হয়েছে?


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@ জোবাডিনিজ (ক এর সাথে using()) যারা ব্যবহার করছেন তাদের জন্য , দয়া করে থামুন! কারণ: aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong
ফিলিপ

উত্তর:


272

এমন দুটি কারণ রয়েছে যে একটি TaskCanceledExceptionনিক্ষেপ করা হবে:

  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)
আরকিউকিউউ

2
@ আরকিউকিউ, আপনি মানুষ, মানুষ! কনস্ট্রাক্টর ব্যবহার না করে আমার জন্য সমস্যার সমাধান হয়েছে। আমার নির্দিষ্ট ক্ষেত্রে, আমি মিলিসেকেন্ডে একটি সময়সীমা চেয়েছিলাম। ব্যবহার TimeSpan.FromMilliseconds(Configuration.HttpTimeout)হিসাবে new TimeSpan(Configuration.HttpTimeout)একটি ট্রিট কাজ বিরোধিতা । ধন্যবাদ!
ভিক্টর উদে

6
@ আরকিউকিউ httpClient.Timeout = TimeSpan.FromMinutes(30)একটি ভাল পদ্ধতির নয়, কারণ এটি 30 মিনিটের জন্য নির্দিষ্ট থ্রেডকে আটকাবে এবং এটি এইচটিটিপি শেষ পয়েন্টেও আঘাত করবে না (এটি আপনার মূল কাজ)। এছাড়াও, যদি আপনার প্রোগ্রামটি 30 মিনিটের আগে শেষ হয় তবে আপনার মুখোমুখি হওয়ার সম্ভাবনা সবচেয়ে বেশি ThreadAbortException। এইচটিটিপি'র শেষ পয়েন্টটি কেন আঘাত হচ্ছে না, এটির জন্য আরও ভাল পদ্ধতির অনুসন্ধান করা হবে, এর জন্য ভিপিএন বা কিছু সীমাবদ্ধ নেটওয়ার্ক অ্যাক্সেসের প্রয়োজন হতে পারে।
অমিত উপাধ্যায়

6
@ অমিতউপাধ্যায় যদি কলটি awaitএড হয়, তবে কোনও থ্রেড অবরুদ্ধ নয়। ইউআই থ্রেড নয়, থ্রেডপুলের থ্রেড নয় অন্য পটভূমি থ্রেড, কোনওটি নয়।
টড মেনিয়ার

20

আমি এই ইস্যুতে দৌড়েছি কারণ আমার Main()পদ্ধতিটি ফিরে আসার আগে টাস্কটি শেষ হওয়ার অপেক্ষায় ছিল না, সুতরাং Task<HttpResponseMessage> myTaskআমার কনসোল প্রোগ্রামটি বের হওয়ার সময় বাতিল করা হচ্ছিল।

সমাধান ডাকতে ছিল myTask.GetAwaiter().GetResult()মধ্যে Main()(থেকে এই উত্তর )।


9

আরেকটি সম্ভাবনা হ'ল ফলটি ক্লায়েন্টের পক্ষে অপেক্ষা করা হয় না। কল স্ট্যাকের যে কোনও একটি পদ্ধতি কলটি সম্পূর্ণ হওয়ার জন্য অপেক্ষা করতে অপেক্ষা করা কীওয়ার্ডটি ব্যবহার না করে তা ঘটতে পারে।


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

একটি বৃহত অনুরোধের জন্য অপেক্ষা করার জন্য উপরেরটি সর্বোত্তম পন্থা। আপনি প্রায় 30 মিনিটের মধ্যে বিভ্রান্ত হয়ে পড়েছেন; এটি এলোমেলো সময় এবং আপনি যে কোনও সময় দিতে পারেন।

অন্য কথায়, অনুরোধটি 30 মিনিটের আগে ফলাফল পেলে 30 মিনিটের জন্য অপেক্ষা করবে না। 30 মিনিট মানে অনুরোধ প্রক্রিয়াকরণের সময় 30 মিনিট। যখন আমাদের ত্রুটি ঘটেছিল তখন "টাস্ক বাতিল করা হয়েছিল", বা বড় ডেটা অনুরোধের প্রয়োজনীয়তা রয়েছে।


0

আর একটি কারণ হ'ল আপনি যদি পরিষেবাটি চালাচ্ছেন (এপিআই) এবং পরিষেবাটিতে একটি ব্রেকপয়েন্ট রেখেছেন (এবং আপনার কোডটি কিছু ব্রেকপয়েন্টে আটকে আছে (যেমন ভিজ্যুয়াল স্টুডিও সমাধানটি রানিংয়ের পরিবর্তে ডিবাগিং দেখাচ্ছে ))। এবং তারপরে ক্লায়েন্ট কোড থেকে API টিপুন। সুতরাং যদি পরিষেবা কোডটি কিছু ব্রেকপয়েন্টে কিছুটা বিরতি দেয়, আপনি কেবল ভিএস-তে F5 চাপুন hit


0

আমার পরিস্থিতিতে নিয়ামক পদ্ধতিটি async হিসাবে তৈরি করা হয়নি এবং নিয়ামক পদ্ধতির অভ্যন্তরে যে পদ্ধতিটি বলা হয় সেটি ছিল async।

সুতরাং আমি এ জাতীয় সমস্যা এড়াতে শীর্ষ স্তরের সমস্ত উপায়ে async ব্যবহার করা / অপেক্ষা করা জরুরী বলে অনুমান করি।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.